diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/video/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/Kconfig | 27 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/Makefile | 13 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bt848.h | 369 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-audio-hook.c | 382 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-audio-hook.h | 23 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-cards.c | 4895 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-driver.c | 4630 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-gpio.c | 189 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-i2c.c | 397 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-if.c | 121 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-input.c | 589 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-risc.c | 909 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-vbi.c | 459 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv.h | 376 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttvp.h | 535 |
17 files changed, 0 insertions, 13917 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index f52799232029..f3d4228dbb0e 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -619,8 +619,6 @@ menuconfig V4L_PCI_DRIVERS if V4L_PCI_DRIVERS -source "drivers/media/video/bt8xx/Kconfig" - source "drivers/media/video/cx18/Kconfig" source "drivers/media/video/cx23885/Kconfig" diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 4ad5bd9246bf..df60ffacdc58 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -87,7 +87,6 @@ obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o # And now the v4l2 drivers: -obj-$(CONFIG_VIDEO_BT848) += bt8xx/ obj-$(CONFIG_VIDEO_ZORAN) += zoran/ obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig deleted file mode 100644 index 7da5c2e1fc12..000000000000 --- a/drivers/media/video/bt8xx/Kconfig +++ /dev/null @@ -1,27 +0,0 @@ -config VIDEO_BT848 - tristate "BT848 Video For Linux" - depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 - select I2C_ALGOBIT - select VIDEO_BTCX - select VIDEOBUF_DMA_SG - depends on RC_CORE - select VIDEO_TUNER - select VIDEO_TVEEPROM - select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO - ---help--- - Support for BT848 based frame grabber/overlay boards. This includes - the Miro, Hauppauge and STB boards. Please read the material in - <file:Documentation/video4linux/bttv/> for more information. - - To compile this driver as a module, choose M here: the - module will be called bttv. - -config VIDEO_BT848_DVB - bool "DVB/ATSC Support for bt878 based TV cards" - depends on VIDEO_BT848 && DVB_CORE - select DVB_BT8XX - ---help--- - This adds support for DVB/ATSC cards based on the BT878 chip. diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile deleted file mode 100644 index f6351a25c267..000000000000 --- a/drivers/media/video/bt8xx/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for the video capture/playback device drivers. -# - -bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ - bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \ - bttv-input.o bttv-audio-hook.o - -obj-$(CONFIG_VIDEO_BT848) += bttv.o - -ccflags-y += -Idrivers/media/video -ccflags-y += -Idrivers/media/tuners -ccflags-y += -Idrivers/media/dvb-core diff --git a/drivers/media/video/bt8xx/bt848.h b/drivers/media/video/bt8xx/bt848.h deleted file mode 100644 index c37e6acffded..000000000000 --- a/drivers/media/video/bt8xx/bt848.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - bt848.h - Bt848 register offsets - - Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _BT848_H_ -#define _BT848_H_ - -#ifndef PCI_VENDOR_ID_BROOKTREE -#define PCI_VENDOR_ID_BROOKTREE 0x109e -#endif -#ifndef PCI_DEVICE_ID_BT848 -#define PCI_DEVICE_ID_BT848 0x350 -#endif -#ifndef PCI_DEVICE_ID_BT849 -#define PCI_DEVICE_ID_BT849 0x351 -#endif -#ifndef PCI_DEVICE_ID_FUSION879 -#define PCI_DEVICE_ID_FUSION879 0x36c -#endif - -#ifndef PCI_DEVICE_ID_BT878 -#define PCI_DEVICE_ID_BT878 0x36e -#endif -#ifndef PCI_DEVICE_ID_BT879 -#define PCI_DEVICE_ID_BT879 0x36f -#endif - -/* Brooktree 848 registers */ - -#define BT848_DSTATUS 0x000 -#define BT848_DSTATUS_PRES (1<<7) -#define BT848_DSTATUS_HLOC (1<<6) -#define BT848_DSTATUS_FIELD (1<<5) -#define BT848_DSTATUS_NUML (1<<4) -#define BT848_DSTATUS_CSEL (1<<3) -#define BT848_DSTATUS_PLOCK (1<<2) -#define BT848_DSTATUS_LOF (1<<1) -#define BT848_DSTATUS_COF (1<<0) - -#define BT848_IFORM 0x004 -#define BT848_IFORM_HACTIVE (1<<7) -#define BT848_IFORM_MUXSEL (3<<5) -#define BT848_IFORM_MUX0 (2<<5) -#define BT848_IFORM_MUX1 (3<<5) -#define BT848_IFORM_MUX2 (1<<5) -#define BT848_IFORM_XTSEL (3<<3) -#define BT848_IFORM_XT0 (1<<3) -#define BT848_IFORM_XT1 (2<<3) -#define BT848_IFORM_XTAUTO (3<<3) -#define BT848_IFORM_XTBOTH (3<<3) -#define BT848_IFORM_NTSC 1 -#define BT848_IFORM_NTSC_J 2 -#define BT848_IFORM_PAL_BDGHI 3 -#define BT848_IFORM_PAL_M 4 -#define BT848_IFORM_PAL_N 5 -#define BT848_IFORM_SECAM 6 -#define BT848_IFORM_PAL_NC 7 -#define BT848_IFORM_AUTO 0 -#define BT848_IFORM_NORM 7 - -#define BT848_TDEC 0x008 -#define BT848_TDEC_DEC_FIELD (1<<7) -#define BT848_TDEC_FLDALIGN (1<<6) -#define BT848_TDEC_DEC_RAT (0x1f) - -#define BT848_E_CROP 0x00C -#define BT848_O_CROP 0x08C - -#define BT848_E_VDELAY_LO 0x010 -#define BT848_O_VDELAY_LO 0x090 - -#define BT848_E_VACTIVE_LO 0x014 -#define BT848_O_VACTIVE_LO 0x094 - -#define BT848_E_HDELAY_LO 0x018 -#define BT848_O_HDELAY_LO 0x098 - -#define BT848_E_HACTIVE_LO 0x01C -#define BT848_O_HACTIVE_LO 0x09C - -#define BT848_E_HSCALE_HI 0x020 -#define BT848_O_HSCALE_HI 0x0A0 - -#define BT848_E_HSCALE_LO 0x024 -#define BT848_O_HSCALE_LO 0x0A4 - -#define BT848_BRIGHT 0x028 - -#define BT848_E_CONTROL 0x02C -#define BT848_O_CONTROL 0x0AC -#define BT848_CONTROL_LNOTCH (1<<7) -#define BT848_CONTROL_COMP (1<<6) -#define BT848_CONTROL_LDEC (1<<5) -#define BT848_CONTROL_CBSENSE (1<<4) -#define BT848_CONTROL_CON_MSB (1<<2) -#define BT848_CONTROL_SAT_U_MSB (1<<1) -#define BT848_CONTROL_SAT_V_MSB (1<<0) - -#define BT848_CONTRAST_LO 0x030 -#define BT848_SAT_U_LO 0x034 -#define BT848_SAT_V_LO 0x038 -#define BT848_HUE 0x03C - -#define BT848_E_SCLOOP 0x040 -#define BT848_O_SCLOOP 0x0C0 -#define BT848_SCLOOP_CAGC (1<<6) -#define BT848_SCLOOP_CKILL (1<<5) -#define BT848_SCLOOP_HFILT_AUTO (0<<3) -#define BT848_SCLOOP_HFILT_CIF (1<<3) -#define BT848_SCLOOP_HFILT_QCIF (2<<3) -#define BT848_SCLOOP_HFILT_ICON (3<<3) - -#define BT848_SCLOOP_PEAK (1<<7) -#define BT848_SCLOOP_HFILT_MINP (1<<3) -#define BT848_SCLOOP_HFILT_MEDP (2<<3) -#define BT848_SCLOOP_HFILT_MAXP (3<<3) - - -#define BT848_OFORM 0x048 -#define BT848_OFORM_RANGE (1<<7) -#define BT848_OFORM_CORE0 (0<<5) -#define BT848_OFORM_CORE8 (1<<5) -#define BT848_OFORM_CORE16 (2<<5) -#define BT848_OFORM_CORE32 (3<<5) - -#define BT848_E_VSCALE_HI 0x04C -#define BT848_O_VSCALE_HI 0x0CC -#define BT848_VSCALE_YCOMB (1<<7) -#define BT848_VSCALE_COMB (1<<6) -#define BT848_VSCALE_INT (1<<5) -#define BT848_VSCALE_HI 15 - -#define BT848_E_VSCALE_LO 0x050 -#define BT848_O_VSCALE_LO 0x0D0 -#define BT848_TEST 0x054 -#define BT848_ADELAY 0x060 -#define BT848_BDELAY 0x064 - -#define BT848_ADC 0x068 -#define BT848_ADC_RESERVED (2<<6) -#define BT848_ADC_SYNC_T (1<<5) -#define BT848_ADC_AGC_EN (1<<4) -#define BT848_ADC_CLK_SLEEP (1<<3) -#define BT848_ADC_Y_SLEEP (1<<2) -#define BT848_ADC_C_SLEEP (1<<1) -#define BT848_ADC_CRUSH (1<<0) - -#define BT848_WC_UP 0x044 -#define BT848_WC_DOWN 0x078 - -#define BT848_E_VTC 0x06C -#define BT848_O_VTC 0x0EC -#define BT848_VTC_HSFMT (1<<7) -#define BT848_VTC_VFILT_2TAP 0 -#define BT848_VTC_VFILT_3TAP 1 -#define BT848_VTC_VFILT_4TAP 2 -#define BT848_VTC_VFILT_5TAP 3 - -#define BT848_SRESET 0x07C - -#define BT848_COLOR_FMT 0x0D4 -#define BT848_COLOR_FMT_O_RGB32 (0<<4) -#define BT848_COLOR_FMT_O_RGB24 (1<<4) -#define BT848_COLOR_FMT_O_RGB16 (2<<4) -#define BT848_COLOR_FMT_O_RGB15 (3<<4) -#define BT848_COLOR_FMT_O_YUY2 (4<<4) -#define BT848_COLOR_FMT_O_BtYUV (5<<4) -#define BT848_COLOR_FMT_O_Y8 (6<<4) -#define BT848_COLOR_FMT_O_RGB8 (7<<4) -#define BT848_COLOR_FMT_O_YCrCb422 (8<<4) -#define BT848_COLOR_FMT_O_YCrCb411 (9<<4) -#define BT848_COLOR_FMT_O_RAW (14<<4) -#define BT848_COLOR_FMT_E_RGB32 0 -#define BT848_COLOR_FMT_E_RGB24 1 -#define BT848_COLOR_FMT_E_RGB16 2 -#define BT848_COLOR_FMT_E_RGB15 3 -#define BT848_COLOR_FMT_E_YUY2 4 -#define BT848_COLOR_FMT_E_BtYUV 5 -#define BT848_COLOR_FMT_E_Y8 6 -#define BT848_COLOR_FMT_E_RGB8 7 -#define BT848_COLOR_FMT_E_YCrCb422 8 -#define BT848_COLOR_FMT_E_YCrCb411 9 -#define BT848_COLOR_FMT_E_RAW 14 - -#define BT848_COLOR_FMT_RGB32 0x00 -#define BT848_COLOR_FMT_RGB24 0x11 -#define BT848_COLOR_FMT_RGB16 0x22 -#define BT848_COLOR_FMT_RGB15 0x33 -#define BT848_COLOR_FMT_YUY2 0x44 -#define BT848_COLOR_FMT_BtYUV 0x55 -#define BT848_COLOR_FMT_Y8 0x66 -#define BT848_COLOR_FMT_RGB8 0x77 -#define BT848_COLOR_FMT_YCrCb422 0x88 -#define BT848_COLOR_FMT_YCrCb411 0x99 -#define BT848_COLOR_FMT_RAW 0xee - -#define BT848_VTOTAL_LO 0xB0 -#define BT848_VTOTAL_HI 0xB4 - -#define BT848_COLOR_CTL 0x0D8 -#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7) -#define BT848_COLOR_CTL_COLOR_BARS (1<<6) -#define BT848_COLOR_CTL_RGB_DED (1<<5) -#define BT848_COLOR_CTL_GAMMA (1<<4) -#define BT848_COLOR_CTL_WSWAP_ODD (1<<3) -#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2) -#define BT848_COLOR_CTL_BSWAP_ODD (1<<1) -#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0) - -#define BT848_CAP_CTL 0x0DC -#define BT848_CAP_CTL_DITH_FRAME (1<<4) -#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3) -#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2) -#define BT848_CAP_CTL_CAPTURE_ODD (1<<1) -#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0) - -#define BT848_VBI_PACK_SIZE 0x0E0 - -#define BT848_VBI_PACK_DEL 0x0E4 -#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc -#define BT848_VBI_PACK_DEL_EXT_FRAME 2 -#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1 - - -#define BT848_INT_STAT 0x100 -#define BT848_INT_MASK 0x104 - -#define BT848_INT_ETBF (1<<23) - -#define BT848_INT_RISCS (0xf<<28) -#define BT848_INT_RISC_EN (1<<27) -#define BT848_INT_RACK (1<<25) -#define BT848_INT_FIELD (1<<24) -#define BT848_INT_SCERR (1<<19) -#define BT848_INT_OCERR (1<<18) -#define BT848_INT_PABORT (1<<17) -#define BT848_INT_RIPERR (1<<16) -#define BT848_INT_PPERR (1<<15) -#define BT848_INT_FDSR (1<<14) -#define BT848_INT_FTRGT (1<<13) -#define BT848_INT_FBUS (1<<12) -#define BT848_INT_RISCI (1<<11) -#define BT848_INT_GPINT (1<<9) -#define BT848_INT_I2CDONE (1<<8) -#define BT848_INT_VPRES (1<<5) -#define BT848_INT_HLOCK (1<<4) -#define BT848_INT_OFLOW (1<<3) -#define BT848_INT_HSYNC (1<<2) -#define BT848_INT_VSYNC (1<<1) -#define BT848_INT_FMTCHG (1<<0) - - -#define BT848_GPIO_DMA_CTL 0x10C -#define BT848_GPIO_DMA_CTL_GPINTC (1<<15) -#define BT848_GPIO_DMA_CTL_GPINTI (1<<14) -#define BT848_GPIO_DMA_CTL_GPWEC (1<<13) -#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11) -#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10) -#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6) -#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6) -#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6) -#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6) -#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4) -#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4) -#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4) -#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4) -#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2) -#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2) -#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2) -#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2) -#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1) -#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0) - -#define BT848_I2C 0x110 -#define BT878_I2C_MODE (1<<7) -#define BT878_I2C_RATE (1<<6) -#define BT878_I2C_NOSTOP (1<<5) -#define BT878_I2C_NOSTART (1<<4) -#define BT848_I2C_DIV (0xf<<4) -#define BT848_I2C_SYNC (1<<3) -#define BT848_I2C_W3B (1<<2) -#define BT848_I2C_SCL (1<<1) -#define BT848_I2C_SDA (1<<0) - -#define BT848_RISC_STRT_ADD 0x114 -#define BT848_GPIO_OUT_EN 0x118 -#define BT848_GPIO_REG_INP 0x11C -#define BT848_RISC_COUNT 0x120 -#define BT848_GPIO_DATA 0x200 - - -/* Bt848 RISC commands */ - -/* only for the SYNC RISC command */ -#define BT848_FIFO_STATUS_FM1 0x06 -#define BT848_FIFO_STATUS_FM3 0x0e -#define BT848_FIFO_STATUS_SOL 0x02 -#define BT848_FIFO_STATUS_EOL4 0x01 -#define BT848_FIFO_STATUS_EOL3 0x0d -#define BT848_FIFO_STATUS_EOL2 0x09 -#define BT848_FIFO_STATUS_EOL1 0x05 -#define BT848_FIFO_STATUS_VRE 0x04 -#define BT848_FIFO_STATUS_VRO 0x0c -#define BT848_FIFO_STATUS_PXV 0x00 - -#define BT848_RISC_RESYNC (1<<15) - -/* WRITE and SKIP */ -/* disable which bytes of each DWORD */ -#define BT848_RISC_BYTE0 (1U<<12) -#define BT848_RISC_BYTE1 (1U<<13) -#define BT848_RISC_BYTE2 (1U<<14) -#define BT848_RISC_BYTE3 (1U<<15) -#define BT848_RISC_BYTE_ALL (0x0fU<<12) -#define BT848_RISC_BYTE_NONE 0 -/* cause RISCI */ -#define BT848_RISC_IRQ (1U<<24) -/* RISC command is last one in this line */ -#define BT848_RISC_EOL (1U<<26) -/* RISC command is first one in this line */ -#define BT848_RISC_SOL (1U<<27) - -#define BT848_RISC_WRITE (0x01U<<28) -#define BT848_RISC_SKIP (0x02U<<28) -#define BT848_RISC_WRITEC (0x05U<<28) -#define BT848_RISC_JUMP (0x07U<<28) -#define BT848_RISC_SYNC (0x08U<<28) - -#define BT848_RISC_WRITE123 (0x09U<<28) -#define BT848_RISC_SKIP123 (0x0aU<<28) -#define BT848_RISC_WRITE1S23 (0x0bU<<28) - - -/* Bt848A and higher only !! */ -#define BT848_TGLB 0x080 -#define BT848_TGCTRL 0x084 -#define BT848_FCAP 0x0E8 -#define BT848_PLL_F_LO 0x0F0 -#define BT848_PLL_F_HI 0x0F4 - -#define BT848_PLL_XCI 0x0F8 -#define BT848_PLL_X (1<<7) -#define BT848_PLL_C (1<<6) - -#define BT848_DVSIF 0x0FC - -/* Bt878 register */ - -#define BT878_DEVCTRL 0x40 -#define BT878_EN_TBFX 0x02 -#define BT878_EN_VSFX 0x04 - -#endif diff --git a/drivers/media/video/bt8xx/bttv-audio-hook.c b/drivers/media/video/bt8xx/bttv-audio-hook.c deleted file mode 100644 index 2364d16586b3..000000000000 --- a/drivers/media/video/bt8xx/bttv-audio-hook.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Handlers for board audio hooks, splitted from bttv-cards - * - * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org) - * This code is placed under the terms of the GNU General Public License - */ - -#include "bttv-audio-hook.h" - -#include <linux/delay.h> - -/* ----------------------------------------------------------------------- */ -/* winview */ - -void winview_volume(struct bttv *btv, __u16 volume) -{ - /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */ - int bits_out, loops, vol, data; - - /* 32 levels logarithmic */ - vol = 32 - ((volume>>11)); - /* units */ - bits_out = (PT2254_DBS_IN_2>>(vol%5)); - /* tens */ - bits_out |= (PT2254_DBS_IN_10>>(vol/5)); - bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL; - data = gpio_read(); - data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA| - WINVIEW_PT2254_STROBE); - for (loops = 17; loops >= 0 ; loops--) { - if (bits_out & (1<<loops)) - data |= WINVIEW_PT2254_DATA; - else - data &= ~WINVIEW_PT2254_DATA; - gpio_write(data); - udelay(5); - data |= WINVIEW_PT2254_CLK; - gpio_write(data); - udelay(5); - data &= ~WINVIEW_PT2254_CLK; - gpio_write(data); - } - data |= WINVIEW_PT2254_STROBE; - data &= ~WINVIEW_PT2254_DATA; - gpio_write(data); - udelay(10); - data &= ~WINVIEW_PT2254_STROBE; - gpio_write(data); -} - -/* ----------------------------------------------------------------------- */ -/* mono/stereo control for various cards (which don't use i2c chips but */ -/* connect something to the GPIO pins */ - -void gvbctv3pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - unsigned int con = 0; - - if (set) { - gpio_inout(0x300, 0x300); - if (t->audmode & V4L2_TUNER_MODE_LANG1) - con = 0x000; - if (t->audmode & V4L2_TUNER_MODE_LANG2) - con = 0x300; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - con = 0x200; -/* if (t->audmode & V4L2_TUNER_MODE_MONO) - * con = 0x100; */ - gpio_bits(0x300, con); - } else { - t->audmode = V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - } -} - -void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - unsigned int val, con; - - if (btv->radio_user) - return; - - val = gpio_read(); - if (set) { - con = 0x000; - if (t->audmode & V4L2_TUNER_MODE_LANG2) { - if (t->audmode & V4L2_TUNER_MODE_LANG1) { - /* LANG1 + LANG2 */ - con = 0x100; - } - else { - /* LANG2 */ - con = 0x300; - } - } - if (con != (val & 0x300)) { - gpio_bits(0x300, con); - if (bttv_gpio) - bttv_gpio_tracking(btv,"gvbctv5pci"); - } - } else { - switch (val & 0x70) { - case 0x10: - t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - break; - case 0x30: - t->rxsubchans = V4L2_TUNER_SUB_LANG2; - break; - case 0x50: - t->rxsubchans = V4L2_TUNER_SUB_LANG1; - break; - case 0x60: - t->rxsubchans = V4L2_TUNER_SUB_STEREO; - break; - case 0x70: - t->rxsubchans = V4L2_TUNER_SUB_MONO; - break; - default: - t->rxsubchans = V4L2_TUNER_SUB_MONO | - V4L2_TUNER_SUB_STEREO | - V4L2_TUNER_SUB_LANG1 | - V4L2_TUNER_SUB_LANG2; - } - t->audmode = V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - } -} - -/* - * Mario Medina Nussbaum <medisoft@alohabbs.org.mx> - * I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo, - * 0xdde enables mono and 0xccd enables sap - * - * Petr Vandrovec <VANDROVE@vc.cvut.cz> - * P.S.: At least mask in line above is wrong - GPIO pins 3,2 select - * input/output sound connection, so both must be set for output mode. - * - * Looks like it's needed only for the "tvphone", the "tvphone 98" - * handles this with a tda9840 - * - */ - -void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - int val = 0; - - if (set) { - if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */ - val = 0x02; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - val = 0x01; - if (val) { - gpio_bits(0x03,val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"avermedia"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1; - return; - } -} - - -void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - int val = 0; - - if (set) { - if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */ - val = 0x01; - if (t->audmode & V4L2_TUNER_MODE_STEREO) /* STEREO */ - val = 0x02; - btaor(val, ~0x03, BT848_GPIO_DATA); - if (bttv_gpio) - bttv_gpio_tracking(btv,"avermedia"); - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - return; - } -} - -/* Lifetec 9415 handling */ - -void lt9415_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - int val = 0; - - if (gpio_read() & 0x4000) { - t->audmode = V4L2_TUNER_MODE_MONO; - return; - } - - if (set) { - if (t->audmode & V4L2_TUNER_MODE_LANG2) /* A2 SAP */ - val = 0x0080; - if (t->audmode & V4L2_TUNER_MODE_STEREO) /* A2 stereo */ - val = 0x0880; - if ((t->audmode & V4L2_TUNER_MODE_LANG1) || - (t->audmode & V4L2_TUNER_MODE_MONO)) - val = 0; - gpio_bits(0x0880, val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"lt9415"); - } else { - /* autodetect doesn't work with this card :-( */ - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - return; - } -} - -/* TDA9821 on TerraTV+ Bt848, Bt878 */ -void terratv_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - unsigned int con = 0; - - if (set) { - gpio_inout(0x180000,0x180000); - if (t->audmode & V4L2_TUNER_MODE_LANG2) - con = 0x080000; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - con = 0x180000; - gpio_bits(0x180000, con); - if (bttv_gpio) - bttv_gpio_tracking(btv,"terratv"); - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - } -} - - -void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - unsigned long val = 0; - - if (set) { - /*btor (0xc32000, BT848_GPIO_OUT_EN);*/ - if (t->audmode & V4L2_TUNER_MODE_MONO) /* Mono */ - val = 0x420000; - if (t->audmode & V4L2_TUNER_MODE_LANG1) /* Mono */ - val = 0x420000; - if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */ - val = 0x410000; - if (t->audmode & V4L2_TUNER_MODE_STEREO) /* Stereo */ - val = 0x020000; - if (val) { - gpio_bits(0x430000, val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"winfast2000"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - } -} - -/* - * Dariusz Kowalewski <darekk@automex.pl> - * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM - * revision 9B has on-board TDA9874A sound decoder). - * - * Note: There are card variants without tda9874a. Forcing the "stereo sound route" - * will mute this cards. - */ -void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - unsigned int val = 0; - - if (btv->radio_user) - return; - - if (set) { - if (t->audmode & V4L2_TUNER_MODE_MONO) { - val = 0x01; - } - if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2)) - || (t->audmode & V4L2_TUNER_MODE_STEREO)) { - val = 0x02; - } - if (val) { - gpio_bits(0x03,val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"pvbt878p9b"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - } -} - -/* - * Dariusz Kowalewski <darekk@automex.pl> - * sound control for FlyVideo 2000S (with tda9874 decoder) - * based on pvbt878p9b_audio() - this is not tested, please fix!!! - */ -void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - unsigned int val = 0xffff; - - if (btv->radio_user) - return; - - if (set) { - if (t->audmode & V4L2_TUNER_MODE_MONO) { - val = 0x0000; - } - if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2)) - || (t->audmode & V4L2_TUNER_MODE_STEREO)) { - val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */ - } - if (val != 0xffff) { - gpio_bits(0x1800, val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"fv2000s"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - } -} - -/* - * sound control for Canopus WinDVR PCI - * Masaki Suzuki <masaki@btree.org> - */ -void windvr_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - unsigned long val = 0; - - if (set) { - if (t->audmode & V4L2_TUNER_MODE_MONO) - val = 0x040000; - if (t->audmode & V4L2_TUNER_MODE_LANG1) - val = 0; - if (t->audmode & V4L2_TUNER_MODE_LANG2) - val = 0x100000; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - val = 0; - if (val) { - gpio_bits(0x140000, val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"windvr"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - } -} - -/* - * sound control for AD-TVK503 - * Hiroshi Takekawa <sian@big.or.jp> - */ -void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *t, int set) -{ - unsigned int con = 0xffffff; - - /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */ - - if (set) { - /* btor(***, BT848_GPIO_OUT_EN); */ - if (t->audmode & V4L2_TUNER_MODE_LANG1) - con = 0x00000000; - if (t->audmode & V4L2_TUNER_MODE_LANG2) - con = 0x00180000; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - con = 0x00000000; - if (t->audmode & V4L2_TUNER_MODE_MONO) - con = 0x00060000; - if (con != 0xffffff) { - gpio_bits(0x1e0000,con); - if (bttv_gpio) - bttv_gpio_tracking(btv, "adtvk503"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; - } -} diff --git a/drivers/media/video/bt8xx/bttv-audio-hook.h b/drivers/media/video/bt8xx/bttv-audio-hook.h deleted file mode 100644 index 159d07adeff8..000000000000 --- a/drivers/media/video/bt8xx/bttv-audio-hook.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Handlers for board audio hooks, splitted from bttv-cards - * - * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org) - * This code is placed under the terms of the GNU General Public License - */ - -#include "bttvp.h" - -void winview_volume (struct bttv *btv, __u16 volume); - -void lt9415_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void terratv_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void gvbctv3pci_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void windvr_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); -void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set); - diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c deleted file mode 100644 index 38952faaffda..000000000000 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ /dev/null @@ -1,4895 +0,0 @@ -/* - - bttv-cards.c - - this file has configuration informations - card-specific stuff - like the big tvcards array for the most part - - Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) - & Marcus Metzler (mocm@thp.uni-koeln.de) - (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/delay.h> -#include <linux/module.h> -#include <linux/kmod.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/vmalloc.h> -#include <linux/firmware.h> -#include <net/checksum.h> - -#include <asm/unaligned.h> -#include <asm/io.h> - -#include "bttvp.h" -#include <media/v4l2-common.h> -#include <media/tvaudio.h> -#include "bttv-audio-hook.h" - -/* fwd decl */ -static void boot_msp34xx(struct bttv *btv, int pin); -static void hauppauge_eeprom(struct bttv *btv); -static void avermedia_eeprom(struct bttv *btv); -static void osprey_eeprom(struct bttv *btv, const u8 ee[256]); -static void modtec_eeprom(struct bttv *btv); -static void init_PXC200(struct bttv *btv); -static void init_RTV24(struct bttv *btv); - -static void rv605_muxsel(struct bttv *btv, unsigned int input); -static void eagle_muxsel(struct bttv *btv, unsigned int input); -static void xguard_muxsel(struct bttv *btv, unsigned int input); -static void ivc120_muxsel(struct bttv *btv, unsigned int input); -static void gvc1100_muxsel(struct bttv *btv, unsigned int input); - -static void PXC200_muxsel(struct bttv *btv, unsigned int input); - -static void picolo_tetra_muxsel(struct bttv *btv, unsigned int input); -static void picolo_tetra_init(struct bttv *btv); - -static void tibetCS16_muxsel(struct bttv *btv, unsigned int input); -static void tibetCS16_init(struct bttv *btv); - -static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input); -static void kodicom4400r_init(struct bttv *btv); - -static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input); -static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input); - -static void geovision_muxsel(struct bttv *btv, unsigned int input); - -static void phytec_muxsel(struct bttv *btv, unsigned int input); - -static void gv800s_muxsel(struct bttv *btv, unsigned int input); -static void gv800s_init(struct bttv *btv); - -static void td3116_muxsel(struct bttv *btv, unsigned int input); - -static int terratec_active_radio_upgrade(struct bttv *btv); -static int tea5757_read(struct bttv *btv); -static int tea5757_write(struct bttv *btv, int value); -static void identify_by_eeprom(struct bttv *btv, - unsigned char eeprom_data[256]); -static int __devinit pvr_boot(struct bttv *btv); - -/* config variables */ -static unsigned int triton1; -static unsigned int vsfx; -static unsigned int latency = UNSET; -int no_overlay=-1; - -static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; -static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; -static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; -static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; -static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; -static unsigned int audiodev[BTTV_MAX]; -static unsigned int saa6588[BTTV_MAX]; -static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL }; -static unsigned int autoload = UNSET; -static unsigned int gpiomask = UNSET; -static unsigned int audioall = UNSET; -static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET }; - -/* insmod options */ -module_param(triton1, int, 0444); -module_param(vsfx, int, 0444); -module_param(no_overlay, int, 0444); -module_param(latency, int, 0444); -module_param(gpiomask, int, 0444); -module_param(audioall, int, 0444); -module_param(autoload, int, 0444); - -module_param_array(card, int, NULL, 0444); -module_param_array(pll, int, NULL, 0444); -module_param_array(tuner, int, NULL, 0444); -module_param_array(svhs, int, NULL, 0444); -module_param_array(remote, int, NULL, 0444); -module_param_array(audiodev, int, NULL, 0444); -module_param_array(audiomux, int, NULL, 0444); - -MODULE_PARM_DESC(triton1,"set ETBF pci config bit " - "[enable bug compatibility for triton1 + others]"); -MODULE_PARM_DESC(vsfx,"set VSFX pci config bit " - "[yet another chipset flaw workaround]"); -MODULE_PARM_DESC(latency,"pci latency timer"); -MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list"); -MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)"); -MODULE_PARM_DESC(tuner,"specify installed tuner type"); -MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore"); -MODULE_PARM_DESC(audiodev, "specify audio device:\n" - "\t\t-1 = no audio\n" - "\t\t 0 = autodetect (default)\n" - "\t\t 1 = msp3400\n" - "\t\t 2 = tda7432\n" - "\t\t 3 = tvaudio"); -MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition."); -MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" - " [some VIA/SIS chipsets are known to have problem with overlay]"); - -/* ----------------------------------------------------------------------- */ -/* list of card IDs for bt878+ cards */ - -static struct CARD { - unsigned id; - int cardnr; - char *name; -} cards[] __devinitdata = { - { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" }, - { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" }, - { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" }, - { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" }, - { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" }, - { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" }, - { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" }, - { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" }, - { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" }, - - { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" }, - { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" }, - - { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, - { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" }, - { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" }, - { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, - { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, - { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, - { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, - { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, - { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, - - { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" }, - /* some cards ship with byteswapped IDs ... */ - { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" }, - { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" }, - /* this seems to happen as well ... */ - { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" }, - - { 0x3000121a, BTTV_BOARD_VOODOOTV_200, "3Dfx VoodooTV 200" }, - { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM" }, - { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" }, - - { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, - { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" }, - { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, - { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, - { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" }, - { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" }, - { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, - - { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" }, - { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" }, - { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" }, - { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" }, - { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" }, - - { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" }, - { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, - { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, - { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" }, - - { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" }, - { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" }, - /* clashes with FlyVideo - *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */ - { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" }, - { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */ - { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */ - { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */ - - { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, - { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, - { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, - { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, - { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, - - { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" }, - { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" }, - { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" }, - { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" }, - { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" }, - - { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" }, - { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" }, - { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" }, - { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" }, - - { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" }, - { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" }, - { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" }, - { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" }, - - { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" }, - { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" }, - { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" }, - { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" }, - { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" }, - { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" }, - { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" }, - { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" }, - { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" }, - { 0xa1550800, BTTV_BOARD_IVC200, "IVC-200" }, - { 0xa1550801, BTTV_BOARD_IVC200, "IVC-200" }, - { 0xa1550802, BTTV_BOARD_IVC200, "IVC-200" }, - { 0xa1550803, BTTV_BOARD_IVC200, "IVC-200" }, - { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xf0500000, BTTV_BOARD_IVCE8784, "IVCE-8784" }, - { 0xf0500001, BTTV_BOARD_IVCE8784, "IVCE-8784" }, - { 0xf0500002, BTTV_BOARD_IVCE8784, "IVCE-8784" }, - { 0xf0500003, BTTV_BOARD_IVCE8784, "IVCE-8784" }, - - { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" }, - { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" }, - - { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, - { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, - { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, - { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, - { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, - { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" }, - - { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" }, - { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, - - { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, - { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, - { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, - { 0x03116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 311" }, - { 0x06116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 611" }, - { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" }, - { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" }, - { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" }, - { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" }, - { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" }, - - { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" }, - { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" }, - - { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" }, - { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" }, - { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, - { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, - - { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" }, - - { 0x53534149, BTTV_BOARD_SSAI_SECURITY, "SSAI Security Video Interface" }, - { 0x5353414a, BTTV_BOARD_SSAI_ULTRASOUND, "SSAI Ultrasound Video Interface" }, - - /* likely broken, vendor id doesn't match the other magic views ... - * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ - - /* Duplicate PCI ID, reconfigure for this board during the eeprom read. - * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */ - - { 0x109e036e, BTTV_BOARD_CONCEPTRONIC_CTVFMI2, "Conceptronic CTVFMi v2"}, - - /* DVB cards (using pci function .1 for mpeg data xfer) */ - { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, - { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, - { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, - { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, - { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" }, - { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, - { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, - { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, - { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, - { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" }, - { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, - { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, - { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, - { 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" }, - { 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" }, - { 0x763d800a, BTTV_BOARD_GEOVISION_GV800S, "GeoVision GV-800(S) (master)" }, - { 0x763d800b, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, - { 0x763d800c, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, - { 0x763d800d, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, - - { 0x15401830, BTTV_BOARD_PV183, "Provideo PV183-1" }, - { 0x15401831, BTTV_BOARD_PV183, "Provideo PV183-2" }, - { 0x15401832, BTTV_BOARD_PV183, "Provideo PV183-3" }, - { 0x15401833, BTTV_BOARD_PV183, "Provideo PV183-4" }, - { 0x15401834, BTTV_BOARD_PV183, "Provideo PV183-5" }, - { 0x15401835, BTTV_BOARD_PV183, "Provideo PV183-6" }, - { 0x15401836, BTTV_BOARD_PV183, "Provideo PV183-7" }, - { 0x15401837, BTTV_BOARD_PV183, "Provideo PV183-8" }, - { 0x3116f200, BTTV_BOARD_TVT_TD3116, "Tongwei Video Technology TD-3116" }, - { 0x02280279, BTTV_BOARD_APOSONIC_WDVR, "Aposonic W-DVR" }, - { 0, -1, NULL } -}; - -/* ----------------------------------------------------------------------- */ -/* array with description for bt848 / bt878 tv/grabber cards */ - -struct tvcard bttv_tvcards[] = { - /* ---- card 0x00 ---------------------------------- */ - [BTTV_BOARD_UNKNOWN] = { - .name = " *** UNKNOWN/GENERIC *** ", - .video_inputs = 4, - .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 0), - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_MIRO] = { - .name = "MIRO PCTV", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_HAUPPAUGE] = { - .name = "Hauppauge (bt848)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_STB] = { - .name = "STB, Gateway P/N 6000699 (bt848)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 4, 0, 2, 3 }, - .gpiomute = 1, - .no_msp34xx = 1, - .tuner_type = TUNER_PHILIPS_NTSC, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - }, - - /* ---- card 0x04 ---------------------------------- */ - [BTTV_BOARD_INTEL] = { - .name = "Intel Create and Share PCI/ Smart Video Recorder III", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = 2, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0 }, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_DIAMOND] = { - .name = "Diamond DTV2000", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 3, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0, 1, 0, 1 }, - .gpiomute = 3, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_AVERMEDIA] = { - .name = "AVerMedia TVPhone", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 3, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomask = 0x0f, - .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, - /* 0x04 for some cards ?? */ - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= avermedia_tvphone_audio, - .has_remote = 1, - }, - [BTTV_BOARD_MATRIX_VISION] = { - .name = "MATRIX-Vision MV-Delta", - .video_inputs = 5, - /* .audio_inputs= 1, */ - .svhs = 3, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0, 0), - .gpiomux = { 0 }, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x08 ---------------------------------- */ - [BTTV_BOARD_FLYVIDEO] = { - .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xc00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0xc00, 0x800, 0x400 }, - .gpiomute = 0xc00, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_TURBOTV] = { - .name = "IMS/IXmicro TurboTV", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 3, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 1, 2, 3 }, - .pll = PLL_28, - .tuner_type = TUNER_TEMIC_PAL, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_HAUPPAUGE878] = { - .name = "Hauppauge (bt878)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x0f, /* old: 7 */ - .muxsel = MUXSEL(2, 0, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_MIROPRO] = { - .name = "MIRO PCTV pro", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x3014f, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x20001,0x10001, 0, 0 }, - .gpiomute = 10, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x0c ---------------------------------- */ - [BTTV_BOARD_ADSTECH_TV] = { - .name = "ADS Technologies Channel Surfer TV (bt848)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 13, 14, 11, 7 }, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_AVERMEDIA98] = { - .name = "AVerMedia TVCapture 98", - .video_inputs = 3, - /* .audio_inputs= 4, */ - .svhs = 2, - .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 13, 14, 11, 7 }, - .msp34xx_alt = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= avermedia_tv_stereo_audio, - .no_gpioirq = 1, - }, - [BTTV_BOARD_VHX] = { - .name = "Aimslab Video Highway Xtreme (VHX)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ - .gpiomute = 4, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_ZOLTRIX] = { - .name = "Zoltrix TV-Max", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 1, 0 }, - .gpiomute = 10, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x10 ---------------------------------- */ - [BTTV_BOARD_PIXVIEWPLAYTV] = { - .name = "Prolink Pixelview PlayTV (bt878)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x01fe00, - .muxsel = MUXSEL(2, 3, 1, 1), - /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */ - .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, - .gpiomute = 0x002000, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_WINVIEW_601] = { - .name = "Leadtek WinView 601", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x8300f8, - .muxsel = MUXSEL(2, 3, 1, 1, 0), - .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, - .gpiomute = 0xcfa007, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - .volume_gpio = winview_volume, - .has_radio = 1, - }, - [BTTV_BOARD_AVEC_INTERCAP] = { - .name = "AVEC Intercapture", - .video_inputs = 3, - /* .audio_inputs= 2, */ - .svhs = 2, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 0, 0, 0 }, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_LIFE_FLYKIT] = { - .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .gpiomask = 0x8dff00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0 }, - .no_msp34xx = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x14 ---------------------------------- */ - [BTTV_BOARD_CEI_RAFFLES] = { - .name = "CEI Raffles Card", - .video_inputs = 3, - /* .audio_inputs= 3, */ - .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 1), - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_CONFERENCETV] = { - .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", - .video_inputs = 4, - /* .audio_inputs= 2, tuner, line in */ - .svhs = 2, - .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL_I, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_PHOEBE_TVMAS] = { - .name = "Askey CPH050/ Phoebe Tv Master + FM", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xc00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 0x800, 0x400 }, - .gpiomute = 0xc00, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_MODTEC_205] = { - .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .has_dig_in = 1, - .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */ - /* .digital_mode= DIGITAL_MODE_CAMERA, */ - .gpiomux = { 0, 0, 0, 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ALPS_TSBB5_PAL_I, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x18 ---------------------------------- */ - [BTTV_BOARD_MAGICTVIEW061] = { - .name = "Askey CPH05X/06X (bt878) [many vendors]", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xe00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = {0x400, 0x400, 0x400, 0x400 }, - .gpiomute = 0xc00, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - .has_radio = 1, /* not every card has radio */ - }, - [BTTV_BOARD_VOBIS_BOOSTAR] = { - .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x1f0fff, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, - .gpiomute = 0x40000, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= terratv_audio, - }, - [BTTV_BOARD_HAUPPAUG_WCAM] = { - .name = "Hauppauge WinCam newer (bt878)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 3, - .gpiomask = 7, - .muxsel = MUXSEL(2, 0, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_MAXI] = { - .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", - .video_inputs = 4, - /* .audio_inputs= 2, */ - .svhs = 2, - .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_SECAM, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x1c ---------------------------------- */ - [BTTV_BOARD_TERRATV] = { - .name = "Terratec TerraTV+ Version 1.1 (bt878)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x1f0fff, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, - .gpiomute = 0x40000, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= terratv_audio, - /* GPIO wiring: - External 20 pin connector (for Active Radio Upgrade board) - gpio00: i2c-sda - gpio01: i2c-scl - gpio02: om5610-data - gpio03: om5610-clk - gpio04: om5610-wre - gpio05: om5610-stereo - gpio06: rds6588-davn - gpio07: Pin 7 n.c. - gpio08: nIOW - gpio09+10: nIOR, nSEL ?? (bt878) - gpio09: nIOR (bt848) - gpio10: nSEL (bt848) - Sound Routing: - gpio16: u2-A0 (1st 4052bt) - gpio17: u2-A1 - gpio18: u2-nEN - gpio19: u4-A0 (2nd 4052) - gpio20: u4-A1 - u4-nEN - GND - Btspy: - 00000 : Cdrom (internal audio input) - 10000 : ext. Video audio input - 20000 : TV Mono - a0000 : TV Mono/2 - 1a0000 : TV Stereo - 30000 : Radio - 40000 : Mute - */ - - }, - [BTTV_BOARD_PXC200] = { - /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ - .name = "Imagenation PXC200", - .video_inputs = 5, - /* .audio_inputs= 1, */ - .svhs = 1, /* was: 4 */ - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0, 0), - .gpiomux = { 0 }, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .muxsel_hook = PXC200_muxsel, - - }, - [BTTV_BOARD_FLYVIDEO_98] = { - .name = "Lifeview FlyVideo 98 LR50", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x1800, /* 0x8dfe00 */ - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x0800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_IPROTV] = { - .name = "Formac iProTV, Formac ProTV I (bt848)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 3, - .gpiomask = 1, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 0, 0, 0 }, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x20 ---------------------------------- */ - [BTTV_BOARD_INTEL_C_S_PCI] = { - .name = "Intel Create and Share PCI/ Smart Video Recorder III", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = 2, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0 }, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_TERRATVALUE] = { - .name = "Terratec TerraTValue Version Bt878", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xffff00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x500, 0, 0x300, 0x900 }, - .gpiomute = 0x900, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_WINFAST2000] = { - .name = "Leadtek WinFast 2000/ WinFast 2000 XP", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - /* TV, CVid, SVid, CVid over SVid connector */ - .muxsel = MUXSEL(2, 3, 1, 1, 0), - /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */ - .gpiomask = 0xb33000, - .gpiomux = { 0x122000,0x1000,0x0000,0x620000 }, - .gpiomute = 0x800000, - /* Audio Routing for "WinFast 2000 XP" (no tv stereo !) - gpio23 -- hef4052:nEnable (0x800000) - gpio12 -- hef4052:A1 - gpio13 -- hef4052:A0 - 0x0000: external audio - 0x1000: FM - 0x2000: TV - 0x3000: n.c. - Note: There exists another variant "Winfast 2000" with tv stereo !? - Note: eeprom only contains FF and pci subsystem id 107d:6606 - */ - .pll = PLL_28, - .has_radio = 1, - .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */ - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= winfast2000_audio, - .has_remote = 1, - }, - [BTTV_BOARD_CHRONOS_VS2] = { - .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", - .video_inputs = 4, - /* .audio_inputs= 3, */ - .svhs = 2, - .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x24 ---------------------------------- */ - [BTTV_BOARD_TYPHOON_TVIEW] = { - .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner", - .video_inputs = 4, - /* .audio_inputs= 3, */ - .svhs = 2, - .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - .has_radio = 1, - }, - [BTTV_BOARD_PXELVWPLTVPRO] = { - .name = "Prolink PixelView PlayTV pro", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xff, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, - .gpiomute = 0x29, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_MAGICTVIEW063] = { - .name = "Askey CPH06X TView99", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x551e00, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0x551400, 0x551200, 0, 0 }, - .gpiomute = 0x551c00, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL_I, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - }, - [BTTV_BOARD_PINNACLE] = { - .name = "Pinnacle PCTV Studio/Rave", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x03000F, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 0xd0001, 0, 0 }, - .gpiomute = 1, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x28 ---------------------------------- */ - [BTTV_BOARD_STB2] = { - .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 4, 0, 2, 3 }, - .gpiomute = 1, - .no_msp34xx = 1, - .tuner_type = TUNER_PHILIPS_NTSC, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - }, - [BTTV_BOARD_AVPHONE98] = { - .name = "AVerMedia TVPhone 98", - .video_inputs = 3, - /* .audio_inputs= 4, */ - .svhs = 2, - .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 13, 4, 11, 7 }, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - .has_radio = 1, - .audio_mode_gpio= avermedia_tvphone_audio, - }, - [BTTV_BOARD_PV951] = { - .name = "ProVideo PV951", /* pic16c54 */ - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 0, 0}, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL_I, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_ONAIR_TV] = { - .name = "Little OnAir TV", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xe00b, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 }, - .gpiomute = 0xff3ffc, - .no_msp34xx = 1, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x2c ---------------------------------- */ - [BTTV_BOARD_SIGMA_TVII_FM] = { - .name = "Sigma TVII-FM", - .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .gpiomask = 3, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 1, 0, 2 }, - .gpiomute = 3, - .no_msp34xx = 1, - .pll = PLL_NONE, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_MATRIX_VISION2] = { - .name = "MATRIX-Vision MV-Delta 2", - .video_inputs = 5, - /* .audio_inputs= 1, */ - .svhs = 3, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0, 0), - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_ZOLTRIX_GENIE] = { - .name = "Zoltrix Genie TV/FM", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xbcf03f, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 }, - .gpiomute = 0xbcb03f, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_TEMIC_4039FR5_NTSC, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_TERRATVRADIO] = { - .name = "Terratec TV/Radio+", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x70000, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, - .gpiomute = 0x40000, - .no_msp34xx = 1, - .pll = PLL_35, - .tuner_type = TUNER_PHILIPS_PAL_I, - .tuner_addr = ADDR_UNSET, - .has_radio = 1, - }, - - /* ---- card 0x30 ---------------------------------- */ - [BTTV_BOARD_DYNALINK] = { - .name = "Askey CPH03x/ Dynalink Magic TView", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = {2,0,0,0 }, - .gpiomute = 1, - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_GVBCTV3PCI] = { - .name = "IODATA GV-BCTV3/PCI", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x010f00, - .muxsel = MUXSEL(2, 3, 0, 0), - .gpiomux = {0x10000, 0, 0x10000, 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ALPS_TSHC6_NTSC, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= gvbctv3pci_audio, - }, - [BTTV_BOARD_PXELVWPLTVPAK] = { - .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", - .video_inputs = 5, - /* .audio_inputs= 1, */ - .svhs = 3, - .has_dig_in = 1, - .gpiomask = 0xAA0000, - .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */ - /* .digital_mode= DIGITAL_MODE_CAMERA, */ - .gpiomux = { 0x20000, 0, 0x80000, 0x80000 }, - .gpiomute = 0xa8000, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL_I, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - /* GPIO wiring: (different from Rev.4C !) - GPIO17: U4.A0 (first hef4052bt) - GPIO19: U4.A1 - GPIO20: U5.A1 (second hef4052bt) - GPIO21: U4.nEN - GPIO22: BT832 Reset Line - GPIO23: A5,A0, U5,nEN - Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22 - */ - }, - [BTTV_BOARD_EAGLE] = { - .name = "Eagle Wireless Capricorn2 (bt878A)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 7, - .muxsel = MUXSEL(2, 0, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, - .pll = PLL_28, - .tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x34 ---------------------------------- */ - [BTTV_BOARD_PINNACLEPRO] = { - /* David Härdeman <david@2gen.com> */ - .name = "Pinnacle PCTV Studio Pro", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 3, - .gpiomask = 0x03000F, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 0xd0001, 0, 0 }, - .gpiomute = 10, - /* sound path (5 sources): - MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable) - 0= ext. Audio IN - 1= from MUX2 - 2= Mono TV sound from Tuner - 3= not connected - MUX2 (mask 0x30000): - 0,2,3= from MSP34xx - 1= FM stereo Radio from Tuner */ - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_TVIEW_RDS_FM] = { - /* Claas Langbehn <claas@bigfoot.com>, - Sven Grothklags <sven@upb.de> */ - .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", - .video_inputs = 4, - /* .audio_inputs= 3, */ - .svhs = 2, - .gpiomask = 0x1c, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 0x10, 8 }, - .gpiomute = 4, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .has_radio = 1, - }, - [BTTV_BOARD_LIFETEC_9415] = { - /* Tim Röstermundt <rosterm@uni-muenster.de> - in de.comp.os.unix.linux.hardware: - options bttv card=0 pll=1 radio=1 gpiomask=0x18e0 - gpiomux =0x44c71f,0x44d71f,0,0x44d71f,0x44dfff - options tuner type=5 */ - .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x18e0, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, - .gpiomute = 0x18e0, - /* For cards with tda9820/tda9821: - 0x0000: Tuner normal stereo - 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) - 0x0880: Tuner A2 stereo */ - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_BESTBUY_EASYTV] = { - /* Miguel Angel Alvarez <maacruz@navegalia.com> - old Easy TV BT848 version (model CPH031) */ - .name = "Askey CPH031/ BESTBUY Easy TV", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xF, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, - .pll = PLL_28, - .tuner_type = TUNER_TEMIC_PAL, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x38 ---------------------------------- */ - [BTTV_BOARD_FLYVIDEO_98FM] = { - /* Gordon Heydon <gjheydon@bigfoot.com ('98) */ - .name = "Lifeview FlyVideo 98FM LR50", - .video_inputs = 4, - /* .audio_inputs= 3, */ - .svhs = 2, - .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - }, - /* This is the ultimate cheapo capture card - * just a BT848A on a small PCB! - * Steve Hosgood <steve@equiinet.com> */ - [BTTV_BOARD_GRANDTEC] = { - .name = "GrandTec 'Grand Video Capture' (Bt848)", - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = 1, - .gpiomask = 0, - .muxsel = MUXSEL(3, 1), - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_35, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_ASKEY_CPH060] = { - /* Daniel Herrington <daniel.herrington@home.com> */ - .name = "Askey CPH060/ Phoebe TV Master Only (No FM)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xe00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, - .gpiomute = 0x800, - .pll = PLL_28, - .tuner_type = TUNER_TEMIC_4036FY5_NTSC, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_ASKEY_CPH03X] = { - /* Matti Mottus <mottus@physic.ut.ee> */ - .name = "Askey CPH03x TV Capturer", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x03000F, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 1, - .pll = PLL_28, - .tuner_type = TUNER_TEMIC_PAL, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - }, - - /* ---- card 0x3c ---------------------------------- */ - [BTTV_BOARD_MM100PCTV] = { - /* Philip Blundell <philb@gnu.org> */ - .name = "Modular Technology MM100PCTV", - .video_inputs = 2, - /* .audio_inputs= 2, */ - .svhs = NO_SVHS, - .gpiomask = 11, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 0, 0, 1 }, - .gpiomute = 8, - .pll = PLL_35, - .tuner_type = TUNER_TEMIC_PAL, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_GMV1] = { - /* Adrian Cox <adrian@humboldt.co.uk */ - .name = "AG Electronics GMV1", - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = 1, - .gpiomask = 0xF, - .muxsel = MUXSEL(2, 2), - .gpiomux = { }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_BESTBUY_EASYTV2] = { - /* Miguel Angel Alvarez <maacruz@navegalia.com> - new Easy TV BT878 version (model CPH061) - special thanks to Informatica Mieres for providing the card */ - .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", - .video_inputs = 3, - /* .audio_inputs= 2, */ - .svhs = 2, - .gpiomask = 0xFF, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 1, 0, 4, 4 }, - .gpiomute = 9, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_ATI_TVWONDER] = { - /* Lukas Gebauer <geby@volny.cz> */ - .name = "ATI TV-Wonder", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xf03f, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0xbffe, 0, 0xbfff, 0 }, - .gpiomute = 0xbffe, - .pll = PLL_28, - .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x40 ---------------------------------- */ - [BTTV_BOARD_ATI_TVWONDERVE] = { - /* Lukas Gebauer <geby@volny.cz> */ - .name = "ATI TV-Wonder VE", - .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .gpiomask = 1, - .muxsel = MUXSEL(2, 3, 0, 1), - .gpiomux = { 0, 0, 1, 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_FLYVIDEO2000] = { - /* DeeJay <deejay@westel900.net (2000S) */ - .name = "Lifeview FlyVideo 2000S LR90", - .video_inputs = 3, - /* .audio_inputs= 3, */ - .svhs = 2, - .gpiomask = 0x18e0, - .muxsel = MUXSEL(2, 3, 0, 1), - /* Radio changed from 1e80 to 0x800 to make - FlyVideo2000S in .hu happy (gm)*/ - /* -dk-???: set mute=0x1800 for tda9874h daughterboard */ - .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, - .gpiomute = 0x1800, - .audio_mode_gpio= fv2000s_audio, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_TERRATVALUER] = { - .name = "Terratec TValueRadio", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0xffff00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, - .gpiomute = 0x900, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .has_radio = 1, - }, - [BTTV_BOARD_GVBCTV4PCI] = { - /* TANAKA Kei <peg00625@nifty.com> */ - .name = "IODATA GV-BCTV4/PCI", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x010f00, - .muxsel = MUXSEL(2, 3, 0, 0), - .gpiomux = {0x10000, 0, 0x10000, 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_SHARP_2U5JF5540_NTSC, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= gvbctv3pci_audio, - }, - - /* ---- card 0x44 ---------------------------------- */ - [BTTV_BOARD_VOODOOTV_FM] = { - .name = "3Dfx VoodooTV FM (Euro)", - /* try "insmod msp3400 simple=0" if you have - * sound problems with this card. */ - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .gpiomask = 0x4f8a00, - /* 0x100000: 1=MSP enabled (0=disable again) - * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ - .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff }, - .gpiomute = 0x947fff, - /* tvtuner, radio, external,internal, mute, stereo - * tuner, Composit, SVid, Composit-on-Svid-adapter */ - .muxsel = MUXSEL(2, 3, 0, 1), - .tuner_type = TUNER_MT2032, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - }, - [BTTV_BOARD_VOODOOTV_200] = { - .name = "VoodooTV 200 (USA)", - /* try "insmod msp3400 simple=0" if you have - * sound problems with this card. */ - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .gpiomask = 0x4f8a00, - /* 0x100000: 1=MSP enabled (0=disable again) - * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ - .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff }, - .gpiomute = 0x947fff, - /* tvtuner, radio, external,internal, mute, stereo - * tuner, Composit, SVid, Composit-on-Svid-adapter */ - .muxsel = MUXSEL(2, 3, 0, 1), - .tuner_type = TUNER_MT2032, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - }, - [BTTV_BOARD_AIMMS] = { - /* Philip Blundell <pb@nexus.co.uk> */ - .name = "Active Imaging AIMMS", - .video_inputs = 1, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .muxsel = MUXSEL(2), - .gpiomask = 0 - }, - [BTTV_BOARD_PV_BT878P_PLUS] = { - /* Tomasz Pyra <hellfire@sedez.iq.pl> */ - .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", - .video_inputs = 3, - /* .audio_inputs= 4, */ - .svhs = 2, - .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ - .gpiomute = 13, - .pll = PLL_28, - .tuner_type = TUNER_LG_PAL_I_FM, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - /* GPIO wiring: - GPIO0: U4.A0 (hef4052bt) - GPIO1: U4.A1 - GPIO2: U4.A1 (second hef4052bt) - GPIO3: U4.nEN, U5.A0, A5.nEN - GPIO8-15: vrd866b ? - */ - }, - [BTTV_BOARD_FLYVIDEO98EZ] = { - .name = "Lifeview FlyVideo 98EZ (capture only) LR51", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = 2, - /* AV1, AV2, SVHS, CVid adapter on SVHS */ - .muxsel = MUXSEL(2, 3, 1, 1), - .pll = PLL_28, - .no_msp34xx = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x48 ---------------------------------- */ - [BTTV_BOARD_PV_BT878P_9B] = { - /* Dariusz Kowalewski <darekk@automex.pl> */ - .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x3f, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, - .gpiomute = 0x09, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */ - .has_radio = 1, /* Note: not all cards have radio */ - .has_remote = 1, - /* GPIO wiring: - GPIO0: A0 hef4052 - GPIO1: A1 hef4052 - GPIO3: nEN hef4052 - GPIO8-15: vrd866b - GPIO20,22,23: R30,R29,R28 - */ - }, - [BTTV_BOARD_SENSORAY311_611] = { - /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ - /* you must jumper JP5 for the 311 card (PC/104+) to work */ - .name = "Sensoray 311/611", - .video_inputs = 5, - /* .audio_inputs= 0, */ - .svhs = 4, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0, 0), - .gpiomux = { 0 }, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_RV605] = { - /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ - .name = "RemoteVision MX (RV605)", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x00, - .gpiomask2 = 0x07ff, - .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), - .no_msp34xx = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .muxsel_hook = rv605_muxsel, - }, - [BTTV_BOARD_POWERCLR_MTV878] = { - .name = "Powercolor MTV878/ MTV878R/ MTV878F", - .video_inputs = 3, - /* .audio_inputs= 2, */ - .svhs = 2, - .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ - .muxsel = MUXSEL(2, 1, 1), - .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 4, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - }, - - /* ---- card 0x4c ---------------------------------- */ - [BTTV_BOARD_WINDVR] = { - /* Masaki Suzuki <masaki@btree.org> */ - .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x140007, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, - .tuner_type = TUNER_PHILIPS_NTSC, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= windvr_audio, - }, - [BTTV_BOARD_GRANDTEC_MULTI] = { - .name = "GrandTec Multi Capture Card (Bt878)", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_KWORLD] = { - .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", - .video_inputs = 4, - /* .audio_inputs= 3, */ - .svhs = 2, - .gpiomask = 7, - /* Tuner, SVid, SVHS, SVid to SVHS connector */ - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio! - * This card lacks external Audio In, so we mute it on Ext. & Int. - * The PCB can take a sbx1637/sbx1673, wiring unknown. - * This card lacks PCI subsystem ID, sigh. - * gpiomux =1: lower volume, 2+3: mute - * btwincap uses 0x80000/0x80003 - */ - .gpiomute = 4, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and - radio signal strength indicators work fine. */ - .has_radio = 1, - /* GPIO Info: - GPIO0,1: HEF4052 A0,A1 - GPIO2: HEF4052 nENABLE - GPIO3-7: n.c. - GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card] - GPIO14,15: ?? - GPIO16-21: n.c. - GPIO22,23: ?? - ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ - }, - [BTTV_BOARD_DSP_TCVIDEO] = { - /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ - .name = "DSP Design TCVIDEO", - .video_inputs = 4, - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 1, 0), - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x50 ---------------------------------- */ - [BTTV_BOARD_HAUPPAUGEPVR] = { - .name = "Hauppauge WinTV PVR", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .muxsel = MUXSEL(2, 0, 1, 1), - .pll = PLL_28, - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - - .gpiomask = 7, - .gpiomux = {7}, - }, - [BTTV_BOARD_GVBCTV5PCI] = { - .name = "IODATA GV-BCTV5/PCI", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x0f0f80, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = {0x030000, 0x010000, 0, 0 }, - .gpiomute = 0x020000, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_NTSC_M, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= gvbctv5pci_audio, - .has_radio = 1, - }, - [BTTV_BOARD_OSPREY1x0] = { - .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ - .video_inputs = 4, /* id-inputs-clock */ - /* .audio_inputs= 0, */ - .svhs = 3, - .muxsel = MUXSEL(3, 2, 0, 1), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - [BTTV_BOARD_OSPREY1x0_848] = { - .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ - .video_inputs = 3, - /* .audio_inputs= 0, */ - .svhs = 2, - .muxsel = MUXSEL(2, 3, 1), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - - /* ---- card 0x54 ---------------------------------- */ - [BTTV_BOARD_OSPREY101_848] = { - .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = 1, - .muxsel = MUXSEL(3, 1), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - [BTTV_BOARD_OSPREY1x1] = { - .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ - .video_inputs = 1, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(0), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - [BTTV_BOARD_OSPREY1x1_SVID] = { - .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = 1, - .muxsel = MUXSEL(0, 1), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - [BTTV_BOARD_OSPREY2xx] = { - .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ - .video_inputs = 1, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(0), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - - /* ---- card 0x58 ---------------------------------- */ - [BTTV_BOARD_OSPREY2x0_SVID] = { - .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ - .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = 1, - .muxsel = MUXSEL(0, 1), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - [BTTV_BOARD_OSPREY2x0] = { - .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */ - .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = 1, - .muxsel = MUXSEL(2, 3), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - [BTTV_BOARD_OSPREY500] = { - .name = "Osprey 500", /* 500 */ - .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = 1, - .muxsel = MUXSEL(2, 3), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - [BTTV_BOARD_OSPREY540] = { - .name = "Osprey 540", /* 540 */ - .video_inputs = 4, - /* .audio_inputs= 1, */ - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - - /* ---- card 0x5C ---------------------------------- */ - [BTTV_BOARD_OSPREY2000] = { - .name = "Osprey 2000", /* 2000 */ - .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = 1, - .muxsel = MUXSEL(2, 3), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ - }, - [BTTV_BOARD_IDS_EAGLE] = { - /* M G Berberich <berberic@forwiss.uni-passau.de> */ - .name = "IDS Eagle", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0, - .muxsel = MUXSEL(2, 2, 2, 2), - .muxsel_hook = eagle_muxsel, - .no_msp34xx = 1, - .pll = PLL_28, - }, - [BTTV_BOARD_PINNACLESAT] = { - .name = "Pinnacle PCTV Sat", - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - .muxsel = MUXSEL(3, 1), - .pll = PLL_28, - .no_gpioirq = 1, - .has_dvb = 1, - }, - [BTTV_BOARD_FORMAC_PROTV] = { - .name = "Formac ProTV II (bt878)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 3, - .gpiomask = 2, - /* TV, Comp1, Composite over SVID con, SVID */ - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 2, 0, 0 }, - .pll = PLL_28, - .has_radio = 1, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - /* sound routing: - GPIO=0x00,0x01,0x03: mute (?) - 0x02: both TV and radio (tuner: FM1216/I) - The card has onboard audio connectors labeled "cdrom" and "board", - not soldered here, though unknown wiring. - Card lacks: external audio in, pci subsystem id. - */ - }, - - /* ---- card 0x60 ---------------------------------- */ - [BTTV_BOARD_MACHTV] = { - .name = "MachTV", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 2, 3}, - .gpiomute = 4, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - }, - [BTTV_BOARD_EURESYS_PICOLO] = { - .name = "Euresys Picolo", - .video_inputs = 3, - /* .audio_inputs= 0, */ - .svhs = 2, - .gpiomask = 0, - .no_msp34xx = 1, - .no_tda7432 = 1, - .muxsel = MUXSEL(2, 0, 1), - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_PV150] = { - /* Luc Van Hoeylandt <luc@e-magic.be> */ - .name = "ProVideo PV150", /* 0x4f */ - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3), - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_AD_TVK503] = { - /* Hiroshi Takekawa <sian@big.or.jp> */ - /* This card lacks subsystem ID */ - .name = "AD-TVK503", /* 0x63 */ - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x001e8007, - .muxsel = MUXSEL(2, 3, 1, 0), - /* Tuner, Radio, external, internal, off, on */ - .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, - .gpiomute = 0x0f, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_NTSC, - .tuner_addr = ADDR_UNSET, - .audio_mode_gpio= adtvk503_audio, - }, - - /* ---- card 0x64 ---------------------------------- */ - [BTTV_BOARD_HERCULES_SM_TV] = { - .name = "Hercules Smart TV Stereo", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x00, - .muxsel = MUXSEL(2, 3, 1, 1), - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - /* Notes: - - card lacks subsystem ID - - stereo variant w/ daughter board with tda9874a @0xb0 - - Audio Routing: - always from tda9874 independent of GPIO (?) - external line in: unknown - - Other chips: em78p156elp @ 0x96 (probably IR remote control) - hef4053 (instead 4052) for unknown function - */ - }, - [BTTV_BOARD_PACETV] = { - .name = "Pace TV & Radio Card", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - /* Tuner, CVid, SVid, CVid over SVid connector */ - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomask = 0, - .no_tda7432 = 1, - .tuner_type = TUNER_PHILIPS_PAL_I, - .tuner_addr = ADDR_UNSET, - .has_radio = 1, - .pll = PLL_28, - /* Bt878, Bt832, FI1246 tuner; no pci subsystem id - only internal line out: (4pin header) RGGL - Radio must be decoded by msp3410d (not routed through)*/ - /* - .digital_mode = DIGITAL_MODE_CAMERA, todo! - */ - }, - [BTTV_BOARD_IVC200] = { - /* Chris Willing <chris@vislab.usyd.edu.au> */ - .name = "IVC-200", - .video_inputs = 1, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0xdf, - .muxsel = MUXSEL(2), - .pll = PLL_28, - }, - [BTTV_BOARD_IVCE8784] = { - .name = "IVCE-8784", - .video_inputs = 1, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0xdf, - .muxsel = MUXSEL(2), - .pll = PLL_28, - }, - [BTTV_BOARD_XGUARD] = { - .name = "Grand X-Guard / Trust 814PCI", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .gpiomask2 = 0xff, - .muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0), - .muxsel_hook = xguard_muxsel, - .no_msp34xx = 1, - .no_tda7432 = 1, - .pll = PLL_28, - }, - - /* ---- card 0x68 ---------------------------------- */ - [BTTV_BOARD_NEBULA_DIGITV] = { - .name = "Nebula Electronics DigiTV", - .video_inputs = 1, - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 1, 0), - .no_msp34xx = 1, - .no_tda7432 = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .has_dvb = 1, - .has_remote = 1, - .gpiomask = 0x1b, - .no_gpioirq = 1, - }, - [BTTV_BOARD_PV143] = { - /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ - .name = "ProVideo PV143", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_VD009X1_VD011_MINIDIN] = { - /* M.Klahr@phytec.de */ - .name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = 3, - .gpiomask = 0x00, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_VD009X1_VD011_COMBI] = { - .name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = 3, - .gpiomask = 0x00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - - /* ---- card 0x6c ---------------------------------- */ - [BTTV_BOARD_VD009_MINIDIN] = { - .name = "PHYTEC VD-009 MiniDIN (bt878)", - .video_inputs = 10, - /* .audio_inputs= 0, */ - .svhs = 9, - .gpiomask = 0x00, - .gpiomask2 = 0x03, /* used for external vodeo mux */ - .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0), - .muxsel_hook = phytec_muxsel, - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_VD009_COMBI] = { - .name = "PHYTEC VD-009 Combi (bt878)", - .video_inputs = 10, - /* .audio_inputs= 0, */ - .svhs = 9, - .gpiomask = 0x00, - .gpiomask2 = 0x03, /* used for external vodeo mux */ - .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1), - .muxsel_hook = phytec_muxsel, - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_IVC100] = { - .name = "IVC-100", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0xdf, - .muxsel = MUXSEL(2, 3, 1, 0), - .pll = PLL_28, - }, - [BTTV_BOARD_IVC120] = { - /* IVC-120G - Alan Garfield <alan@fromorbit.com> */ - .name = "IVC-120G", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, /* card has no svhs */ - .no_msp34xx = 1, - .no_tda7432 = 1, - .gpiomask = 0x00, - .muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - .muxsel_hook = ivc120_muxsel, - .pll = PLL_28, - }, - - /* ---- card 0x70 ---------------------------------- */ - [BTTV_BOARD_PC_HDTV] = { - .name = "pcHDTV HD-2000 TV", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 0), - .tuner_type = TUNER_PHILIPS_FCV1236D, - .tuner_addr = ADDR_UNSET, - .has_dvb = 1, - }, - [BTTV_BOARD_TWINHAN_DST] = { - .name = "Twinhan DST + clones", - .no_msp34xx = 1, - .no_tda7432 = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_video = 1, - .has_dvb = 1, - }, - [BTTV_BOARD_WINFASTVC100] = { - .name = "Winfast VC100", - .video_inputs = 3, - /* .audio_inputs= 0, */ - .svhs = 1, - /* Vid In, SVid In, Vid over SVid in connector */ - .muxsel = MUXSEL(3, 1, 1, 3), - .no_msp34xx = 1, - .no_tda7432 = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - }, - [BTTV_BOARD_TEV560] = { - .name = "Teppro TEV-560/InterVision IV-560", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 3, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 1, 1, 1 }, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .pll = PLL_35, - }, - - /* ---- card 0x74 ---------------------------------- */ - [BTTV_BOARD_SIMUS_GVC1100] = { - .name = "SIMUS GVC1100", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .muxsel = MUXSEL(2, 2, 2, 2), - .gpiomask = 0x3F, - .muxsel_hook = gvc1100_muxsel, - }, - [BTTV_BOARD_NGSTV_PLUS] = { - /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ - .name = "NGS NGSTV+", - .video_inputs = 3, - .svhs = 2, - .gpiomask = 0x008007, - .muxsel = MUXSEL(2, 3, 0, 0), - .gpiomux = { 0, 0, 0, 0 }, - .gpiomute = 0x000003, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - }, - [BTTV_BOARD_LMLBT4] = { - /* http://linuxmedialabs.com */ - .name = "LMLBT4", - .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 1, 0), - .no_msp34xx = 1, - .no_tda7432 = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_TEKRAM_M205] = { - /* Helmroos Harri <harri.helmroos@pp.inet.fi> */ - .name = "Tekram M205 PRO", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .svhs = 2, - .gpiomask = 0x68, - .muxsel = MUXSEL(2, 3, 1), - .gpiomux = { 0x68, 0x68, 0x61, 0x61 }, - .pll = PLL_28, - }, - - /* ---- card 0x78 ---------------------------------- */ - [BTTV_BOARD_CONTVFMI] = { - /* Javier Cendan Ares <jcendan@lycos.es> */ - /* bt878 TV + FM without subsystem ID */ - .name = "Conceptronic CONTVFMi", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x008007, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 3, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - .has_radio = 1, - }, - [BTTV_BOARD_PICOLO_TETRA_CHIP] = { - /*Eric DEBIEF <debief@telemsa.com>*/ - /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controlled*/ - /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the following declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/ - /*0x79 in bttv.h*/ - .name = "Euresys Picolo Tetra", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0, - .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ - .no_msp34xx = 1, - .no_tda7432 = 1, - /*878A input is always MUX0, see above.*/ - .muxsel = MUXSEL(2, 2, 2, 2), - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .pll = PLL_28, - .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_SPIRIT_TV] = { - /* Spirit TV Tuner from http://spiritmodems.com.au */ - /* Stafford Goodsell <surge@goliath.homeunix.org> */ - .name = "Spirit TV Tuner", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x0000000f, - .muxsel = MUXSEL(2, 1, 1), - .gpiomux = { 0x02, 0x00, 0x00, 0x00 }, - .tuner_type = TUNER_TEMIC_PAL, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - }, - [BTTV_BOARD_AVDVBT_771] = { - /* Wolfram Joost <wojo@frokaschwei.de> */ - .name = "AVerMedia AVerTV DVB-T 771", - .video_inputs = 2, - .svhs = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .muxsel = MUXSEL(3, 3), - .no_msp34xx = 1, - .no_tda7432 = 1, - .pll = PLL_28, - .has_dvb = 1, - .no_gpioirq = 1, - .has_remote = 1, - }, - /* ---- card 0x7c ---------------------------------- */ - [BTTV_BOARD_AVDVBT_761] = { - /* Matt Jesson <dvb@jesson.eclipse.co.uk> */ - /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */ - .name = "AverMedia AverTV DVB-T 761", - .video_inputs = 2, - .svhs = 1, - .muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */ - .no_msp34xx = 1, - .no_tda7432 = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .has_dvb = 1, - .no_gpioirq = 1, - .has_remote = 1, - }, - [BTTV_BOARD_MATRIX_VISIONSQ] = { - /* andre.schwarz@matrix-vision.de */ - .name = "MATRIX Vision Sigma-SQ", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x0, - .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3), - .muxsel_hook = sigmaSQ_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_MATRIX_VISIONSLC] = { - /* andre.schwarz@matrix-vision.de */ - .name = "MATRIX Vision Sigma-SLC", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x0, - .muxsel = MUXSEL(2, 2, 2, 2), - .muxsel_hook = sigmaSLC_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - /* BTTV_BOARD_APAC_VIEWCOMP */ - [BTTV_BOARD_APAC_VIEWCOMP] = { - /* Attila Kondoros <attila.kondoros@chello.hu> */ - /* bt878 TV + FM 0x00000000 subsystem ID */ - .name = "APAC Viewcomp 878(AMAX)", - .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .gpiomask = 0xFF, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ - .has_radio = 1, /* not every card has radio */ - }, - - /* ---- card 0x80 ---------------------------------- */ - [BTTV_BOARD_DVICO_DVBT_LITE] = { - /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ - .name = "DViCO FusionHDTV DVB-T Lite", - .no_msp34xx = 1, - .no_tda7432 = 1, - .pll = PLL_28, - .no_video = 1, - .has_dvb = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_VGEAR_MYVCD] = { - /* Steven <photon38@pchome.com.tw> */ - .name = "V-Gear MyVCD", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x3f, - .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = {0x31, 0x31, 0x31, 0x31 }, - .gpiomute = 0x31, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_NTSC_M, - .tuner_addr = ADDR_UNSET, - .has_radio = 0, - }, - [BTTV_BOARD_SUPER_TV] = { - /* Rick C <cryptdragoon@gmail.com> */ - .name = "Super TV Tuner", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 0), - .tuner_type = TUNER_PHILIPS_NTSC, - .tuner_addr = ADDR_UNSET, - .gpiomask = 0x008007, - .gpiomux = { 0, 0x000001,0,0 }, - .has_radio = 1, - }, - [BTTV_BOARD_TIBET_CS16] = { - /* Chris Fanning <video4linux@haydon.net> */ - .name = "Tibet Systems 'Progress DVR' CS16", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), - .pll = PLL_28, - .no_msp34xx = 1, - .no_tda7432 = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .muxsel_hook = tibetCS16_muxsel, - }, - [BTTV_BOARD_KODICOM_4400R] = { - /* Bill Brack <wbrack@mmm.com.hk> */ - /* - * Note that, because of the card's wiring, the "master" - * BT878A chip (i.e. the one which controls the analog switch - * and must use this card type) is the 2nd one detected. The - * other 3 chips should use card type 0x85, whose description - * follows this one. There is a EEPROM on the card (which is - * connected to the I2C of one of those other chips), but is - * not currently handled. There is also a facility for a - * "monitor", which is also not currently implemented. - */ - .name = "Kodicom 4400R (master)", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - /* GPIO bits 0-9 used for analog switch: - * 00 - 03: camera selector - * 04 - 06: channel (controller) selector - * 07: data (1->on, 0->off) - * 08: strobe - * 09: reset - * bit 16 is input from sync separator for the channel - */ - .gpiomask = 0x0003ff, - .no_gpioirq = 1, - .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), - .pll = PLL_28, - .no_msp34xx = 1, - .no_tda7432 = 1, - .muxsel_hook = kodicom4400r_muxsel, - }, - [BTTV_BOARD_KODICOM_4400R_SL] = { - /* Bill Brack <wbrack@mmm.com.hk> */ - /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the - * one which controls the analog switch, and must use the card type) - * is the 2nd one detected. The other 3 chips should use this card - * type - */ - .name = "Kodicom 4400R (slave)", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0x010000, - .no_gpioirq = 1, - .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), - .pll = PLL_28, - .no_msp34xx = 1, - .no_tda7432 = 1, - .muxsel_hook = kodicom4400r_muxsel, - }, - /* ---- card 0x86---------------------------------- */ - [BTTV_BOARD_ADLINK_RTV24] = { - /* Michael Henson <mhenson@clarityvi.com> */ - /* Adlink RTV24 with special unlock codes */ - .name = "Adlink RTV24", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 0), - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - }, - /* ---- card 0x87---------------------------------- */ - [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { - /* Michael Krufky <mkrufky@m1k.net> */ - .name = "DViCO FusionHDTV 5 Lite", - .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ - .tuner_addr = ADDR_UNSET, - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .muxsel = MUXSEL(2, 3, 1), - .gpiomask = 0x00e00007, - .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, - .gpiomute = 0x00c00007, - .no_msp34xx = 1, - .no_tda7432 = 1, - .has_dvb = 1, - }, - /* ---- card 0x88---------------------------------- */ - [BTTV_BOARD_ACORP_Y878F] = { - /* Mauro Carvalho Chehab <mchehab@infradead.org> */ - .name = "Acorp Y878F", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x01fe00, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, - .gpiomute = 0x002000, - .pll = PLL_28, - .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, - .tuner_addr = 0xc1 >>1, - .has_radio = 1, - }, - /* ---- card 0x89 ---------------------------------- */ - [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = { - .name = "Conceptronic CTVFMi v2", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x001c0007, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 3, - .pll = PLL_28, - .tuner_type = TUNER_TENA_9533_DI, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - .has_radio = 1, - }, - /* ---- card 0x8a ---------------------------------- */ - [BTTV_BOARD_PV_BT878P_2E] = { - .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)", - .video_inputs = 5, - /* .audio_inputs= 1, */ - .svhs = 3, - .has_dig_in = 1, - .gpiomask = 0x01fe00, - .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */ - /* .digital_mode= DIGITAL_MODE_CAMERA, */ - .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 }, - .gpiomute = 0x12400, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_LG_PAL_FM, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, - }, - /* ---- card 0x8b ---------------------------------- */ - [BTTV_BOARD_PV_M4900] = { - /* Sérgio Fortier <sergiofortier@yahoo.com.br> */ - .name = "Prolink PixelView PlayTV MPEG2 PV-M4900", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x3f, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, - .gpiomute = 0x29, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_YMEC_TVF_5533MF, - .tuner_addr = ADDR_UNSET, - .has_radio = 1, - .has_remote = 1, - }, - /* ---- card 0x8c ---------------------------------- */ - /* Has four Bt878 chips behind a PCI bridge, each chip has: - one external BNC composite input (mux 2) - three internal composite inputs (unknown muxes) - an 18-bit stereo A/D (CS5331A), which has: - one external stereo unblanced (RCA) audio connection - one (or 3?) internal stereo balanced (XLR) audio connection - input is selected via gpio to a 14052B mux - (mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300) - gain is controlled via an X9221A chip on the I2C bus @0x28 - sample rate is controlled via gpio to an MK1413S - (mask=0x3, 32kHz=0x0, 44.1kHz=0x1, 48kHz=0x2, ??=0x3) - There is neither a tuner nor an svideo input. */ - [BTTV_BOARD_OSPREY440] = { - .name = "Osprey 440", - .video_inputs = 4, - /* .audio_inputs= 2, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */ - .gpiomask = 0x303, - .gpiomute = 0x000, /* int + 32kHz */ - .gpiomux = { 0, 0, 0x000, 0x100}, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - /* ---- card 0x8d ---------------------------------- */ - [BTTV_BOARD_ASOUND_SKYEYE] = { - .name = "Asound Skyeye PCTV", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 1, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_NTSC, - .tuner_addr = ADDR_UNSET, - }, - /* ---- card 0x8e ---------------------------------- */ - [BTTV_BOARD_SABRENT_TVFM] = { - .name = "Sabrent TV-FM (bttv version)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x108007, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 100000, 100002, 100002, 100000 }, - .no_msp34xx = 1, - .no_tda7432 = 1, - .pll = PLL_28, - .tuner_type = TUNER_TNF_5335MF, - .tuner_addr = ADDR_UNSET, - .has_radio = 1, - }, - /* ---- card 0x8f ---------------------------------- */ - [BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = { - .name = "Hauppauge ImpactVCB (bt878)", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x0f, /* old: 7 */ - .muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */ - .no_msp34xx = 1, - .no_tda7432 = 1, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_MACHTV_MAGICTV] = { - /* Julian Calaby <julian.calaby@gmail.com> - * Slightly different from original MachTV definition (0x60) - - * FIXME: RegSpy says gpiomask should be "0x001c800f", but it - * stuffs up remote chip. Bug is a pin on the jaecs is not set - * properly (methinks) causing no keyup bits being set */ - - .name = "MagicTV", /* rebranded MachTV */ - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, - .tuner_type = TUNER_TEMIC_4009FR5_PAL, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - .has_remote = 1, - }, - [BTTV_BOARD_SSAI_SECURITY] = { - .name = "SSAI Security Video Interface", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(0, 1, 2, 3), - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_SSAI_ULTRASOUND] = { - .name = "SSAI Ultrasound Video Interface", - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = 1, - .muxsel = MUXSEL(2, 0, 1, 3), - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - /* ---- card 0x94---------------------------------- */ - [BTTV_BOARD_DVICO_FUSIONHDTV_2] = { - .name = "DViCO FusionHDTV 2", - .tuner_type = TUNER_PHILIPS_FCV1236D, - .tuner_addr = ADDR_UNSET, - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .muxsel = MUXSEL(2, 3, 1), - .gpiomask = 0x00e00007, - .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, - .gpiomute = 0x00c00007, - .no_msp34xx = 1, - .no_tda7432 = 1, - }, - /* ---- card 0x95---------------------------------- */ - [BTTV_BOARD_TYPHOON_TVTUNERPCI] = { - .name = "Typhoon TV-Tuner PCI (50684)", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x3014f, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x20001,0x10001, 0, 0 }, - .gpiomute = 10, - .pll = PLL_28, - .tuner_type = TUNER_PHILIPS_PAL_I, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_GEOVISION_GV600] = { - /* emhn@usb.ve */ - .name = "Geovision GV-600", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x0, - .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), - .muxsel_hook = geovision_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_KOZUMI_KTV_01C] = { - /* Mauro Lacy <mauro@lacy.com.ar> - * Based on MagicTV and Conceptronic CONTVFMi */ - - .name = "Kozumi KTV-01C", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - .gpiomask = 0x008007, - .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ - .gpiomute = 3, /* CONTVFMi */ - .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - .has_remote = 1, - }, - [BTTV_BOARD_ENLTV_FM_2] = { - /* Encore TV Tuner Pro ENL TV-FM-2 - Mauro Carvalho Chehab <mchehab@infradead.org */ - .name = "Encore ENL TV-FM-2", - .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = 2, - /* bit 6 -> IR disabled - bit 18/17 = 00 -> mute - 01 -> enable external audio input - 10 -> internal audio input (mono?) - 11 -> internal audio input - */ - .gpiomask = 0x060040, - .muxsel = MUXSEL(2, 3, 3), - .gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 }, - .gpiomute = 0, - .tuner_type = TUNER_TCL_MF02GIP_5N, - .tuner_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - .has_remote = 1, - }, - [BTTV_BOARD_VD012] = { - /* D.Heer@Phytec.de */ - .name = "PHYTEC VD-012 (bt878)", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x00, - .muxsel = MUXSEL(0, 2, 3, 1), - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_VD012_X1] = { - /* D.Heer@Phytec.de */ - .name = "PHYTEC VD-012-X1 (bt878)", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = 3, - .gpiomask = 0x00, - .muxsel = MUXSEL(2, 3, 1), - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_VD012_X2] = { - /* D.Heer@Phytec.de */ - .name = "PHYTEC VD-012-X2 (bt878)", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = 3, - .gpiomask = 0x00, - .muxsel = MUXSEL(3, 2, 1), - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_GEOVISION_GV800S] = { - /* Bruno Christo <bchristo@inf.ufsm.br> - * - * GeoVision GV-800(S) has 4 Conexant Fusion 878A: - * 1 audio input per BT878A = 4 audio inputs - * 4 video inputs per BT878A = 16 video inputs - * This is the first BT878A chip of the GV-800(S). It's the - * "master" chip and it controls the video inputs through an - * analog multiplexer (a CD22M3494) via some GPIO pins. The - * slaves should use card type 0x9e (following this one). - * There is a EEPROM on the card which is currently not handled. - * The audio input is not working yet. - */ - .name = "Geovision GV-800(S) (master)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0xf107f, - .no_gpioirq = 1, - .muxsel = MUXSEL(2, 2, 2, 2), - .pll = PLL_28, - .no_msp34xx = 1, - .no_tda7432 = 1, - .muxsel_hook = gv800s_muxsel, - }, - [BTTV_BOARD_GEOVISION_GV800S_SL] = { - /* Bruno Christo <bchristo@inf.ufsm.br> - * - * GeoVision GV-800(S) has 4 Conexant Fusion 878A: - * 1 audio input per BT878A = 4 audio inputs - * 4 video inputs per BT878A = 16 video inputs - * The 3 other BT878A chips are "slave" chips of the GV-800(S) - * and should use this card type. - * The audio input is not working yet. - */ - .name = "Geovision GV-800(S) (slave)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0x00, - .no_gpioirq = 1, - .muxsel = MUXSEL(2, 2, 2, 2), - .pll = PLL_28, - .no_msp34xx = 1, - .no_tda7432 = 1, - .muxsel_hook = gv800s_muxsel, - }, - [BTTV_BOARD_PV183] = { - .name = "ProVideo PV183", /* 0x9f */ - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3), - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_TVT_TD3116] = { - .name = "Tongwei Video Technology TD-3116", - .video_inputs = 16, - .gpiomask = 0xc00ff, - .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), - .muxsel_hook = td3116_muxsel, - .svhs = NO_SVHS, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - }, - [BTTV_BOARD_APOSONIC_WDVR] = { - .name = "Aposonic W-DVR", - .video_inputs = 4, - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 1, 0), - .tuner_type = TUNER_ABSENT, - }, - -}; - -static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); - -/* ----------------------------------------------------------------------- */ - -static unsigned char eeprom_data[256]; - -/* - * identify card - */ -void __devinit bttv_idcard(struct bttv *btv) -{ - unsigned int gpiobits; - int i,type; - - /* read PCI subsystem ID */ - btv->cardid = btv->c.pci->subsystem_device << 16; - btv->cardid |= btv->c.pci->subsystem_vendor; - - if (0 != btv->cardid && 0xffffffff != btv->cardid) { - /* look for the card */ - for (type = -1, i = 0; cards[i].id != 0; i++) - if (cards[i].id == btv->cardid) - type = i; - - if (type != -1) { - /* found it */ - pr_info("%d: detected: %s [card=%d], PCI subsystem ID is %04x:%04x\n", - btv->c.nr, cards[type].name, cards[type].cardnr, - btv->cardid & 0xffff, - (btv->cardid >> 16) & 0xffff); - btv->c.type = cards[type].cardnr; - } else { - /* 404 */ - pr_info("%d: subsystem: %04x:%04x (UNKNOWN)\n", - btv->c.nr, btv->cardid & 0xffff, - (btv->cardid >> 16) & 0xffff); - pr_debug("please mail id, board name and the correct card= insmod option to linux-media@vger.kernel.org\n"); - } - } - - /* let the user override the autodetected type */ - if (card[btv->c.nr] < bttv_num_tvcards) - btv->c.type=card[btv->c.nr]; - - /* print which card config we are using */ - pr_info("%d: using: %s [card=%d,%s]\n", - btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type, - card[btv->c.nr] < bttv_num_tvcards - ? "insmod option" : "autodetected"); - - /* overwrite gpio stuff ?? */ - if (UNSET == audioall && UNSET == audiomux[0]) - return; - - if (UNSET != audiomux[0]) { - gpiobits = 0; - for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) { - bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i]; - gpiobits |= audiomux[i]; - } - } else { - gpiobits = audioall; - for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) { - bttv_tvcards[btv->c.type].gpiomux[i] = audioall; - } - } - bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits; - pr_info("%d: gpio config override: mask=0x%x, mux=", - btv->c.nr, bttv_tvcards[btv->c.type].gpiomask); - for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) { - pr_cont("%s0x%x", - i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]); - } - pr_cont("\n"); -} - -/* - * (most) board specific initialisations goes here - */ - -/* Some Modular Technology cards have an eeprom, but no subsystem ID */ -static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256]) -{ - int type = -1; - - if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) - type = BTTV_BOARD_MODTEC_205; - else if (0 == strncmp(eeprom_data+20,"Picolo",7)) - type = BTTV_BOARD_EURESYS_PICOLO; - else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0) - type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */ - - if (-1 != type) { - btv->c.type = type; - pr_info("%d: detected by eeprom: %s [card=%d]\n", - btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type); - } -} - -static void flyvideo_gpio(struct bttv *btv) -{ - int gpio, has_remote, has_radio, is_capture_only; - int is_lr90, has_tda9820_tda9821; - int tuner_type = UNSET, ttype; - - gpio_inout(0xffffff, 0); - udelay(8); /* without this we would see the 0x1800 mask */ - gpio = gpio_read(); - /* FIXME: must restore OUR_EN ??? */ - - /* all cards provide GPIO info, some have an additional eeprom - * LR50: GPIO coding can be found lower right CP1 .. CP9 - * CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1. - * GPIO14-12: n.c. - * LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878) - - * lowest 3 bytes are remote control codes (no handshake needed) - * xxxFFF: No remote control chip soldered - * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered - * Note: Some bits are Audio_Mask ! - */ - ttype = (gpio & 0x0f0000) >> 16; - switch (ttype) { - case 0x0: - tuner_type = 2; /* NTSC, e.g. TPI8NSR11P */ - break; - case 0x2: - tuner_type = 39; /* LG NTSC (newer TAPC series) TAPC-H701P */ - break; - case 0x4: - tuner_type = 5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ - break; - case 0x6: - tuner_type = 37; /* LG PAL (newer TAPC series) TAPC-G702P */ - break; - case 0xC: - tuner_type = 3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */ - break; - default: - pr_info("%d: FlyVideo_gpio: unknown tuner type\n", btv->c.nr); - break; - } - - has_remote = gpio & 0x800000; - has_radio = gpio & 0x400000; - /* unknown 0x200000; - * unknown2 0x100000; */ - is_capture_only = !(gpio & 0x008000); /* GPIO15 */ - has_tda9820_tda9821 = !(gpio & 0x004000); - is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */ - /* - * gpio & 0x001000 output bit for audio routing */ - - if (is_capture_only) - tuner_type = TUNER_ABSENT; /* No tuner present */ - - pr_info("%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", - btv->c.nr, has_radio ? "yes" : "no", - has_remote ? "yes" : "no", tuner_type, gpio); - pr_info("%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n", - btv->c.nr, is_lr90 ? "yes" : "no", - has_tda9820_tda9821 ? "yes" : "no", - is_capture_only ? "yes" : "no"); - - if (tuner_type != UNSET) /* only set if known tuner autodetected, else let insmod option through */ - btv->tuner_type = tuner_type; - btv->has_radio = has_radio; - - /* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80 - * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00 - * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */ - if (has_tda9820_tda9821) - btv->audio_mode_gpio = lt9415_audio; - /* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */ -} - -static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1, - 14,2,17,1, 4,1,4,3, 1,2,16,1, 4,4,4,4 }; -static int miro_fmtuner[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, - 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,1,0,0 }; - -static void miro_pinnacle_gpio(struct bttv *btv) -{ - int id,msp,gpio; - char *info; - - gpio_inout(0xffffff, 0); - gpio = gpio_read(); - id = ((gpio>>10) & 63) -1; - msp = bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx"); - if (id < 32) { - btv->tuner_type = miro_tunermap[id]; - if (0 == (gpio & 0x20)) { - btv->has_radio = 1; - if (!miro_fmtuner[id]) { - btv->has_matchbox = 1; - btv->mbox_we = (1<<6); - btv->mbox_most = (1<<7); - btv->mbox_clk = (1<<8); - btv->mbox_data = (1<<9); - btv->mbox_mask = (1<<6)|(1<<7)|(1<<8)|(1<<9); - } - } else { - btv->has_radio = 0; - } - if (-1 != msp) { - if (btv->c.type == BTTV_BOARD_MIRO) - btv->c.type = BTTV_BOARD_MIROPRO; - if (btv->c.type == BTTV_BOARD_PINNACLE) - btv->c.type = BTTV_BOARD_PINNACLEPRO; - } - pr_info("%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", - btv->c.nr, id+1, btv->tuner_type, - !btv->has_radio ? "no" : - (btv->has_matchbox ? "matchbox" : "fmtuner"), - (-1 == msp) ? "no" : "yes"); - } else { - /* new cards with microtune tuner */ - id = 63 - id; - btv->has_radio = 0; - switch (id) { - case 1: - info = "PAL / mono"; - btv->tda9887_conf = TDA9887_INTERCARRIER; - break; - case 2: - info = "PAL+SECAM / stereo"; - btv->has_radio = 1; - btv->tda9887_conf = TDA9887_QSS; - break; - case 3: - info = "NTSC / stereo"; - btv->has_radio = 1; - btv->tda9887_conf = TDA9887_QSS; - break; - case 4: - info = "PAL+SECAM / mono"; - btv->tda9887_conf = TDA9887_QSS; - break; - case 5: - info = "NTSC / mono"; - btv->tda9887_conf = TDA9887_INTERCARRIER; - break; - case 6: - info = "NTSC / stereo"; - btv->tda9887_conf = TDA9887_INTERCARRIER; - break; - case 7: - info = "PAL / stereo"; - btv->tda9887_conf = TDA9887_INTERCARRIER; - break; - default: - info = "oops: unknown card"; - break; - } - if (-1 != msp) - btv->c.type = BTTV_BOARD_PINNACLEPRO; - pr_info("%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", - btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); - btv->tuner_type = TUNER_MT2032; - } -} - -/* GPIO21 L: Buffer aktiv, H: Buffer inaktiv */ -#define LM1882_SYNC_DRIVE 0x200000L - -static void init_ids_eagle(struct bttv *btv) -{ - gpio_inout(0xffffff,0xFFFF37); - gpio_write(0x200020); - - /* flash strobe inverter ?! */ - gpio_write(0x200024); - - /* switch sync drive off */ - gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE); - - /* set BT848 muxel to 2 */ - btaor((2)<<5, ~(2<<5), BT848_IFORM); -} - -/* Muxsel helper for the IDS Eagle. - * the eagles does not use the standard muxsel-bits but - * has its own multiplexer */ -static void eagle_muxsel(struct bttv *btv, unsigned int input) -{ - gpio_bits(3, input & 3); - - /* composite */ - /* set chroma ADC to sleep */ - btor(BT848_ADC_C_SLEEP, BT848_ADC); - /* set to composite video */ - btand(~BT848_CONTROL_COMP, BT848_E_CONTROL); - btand(~BT848_CONTROL_COMP, BT848_O_CONTROL); - - /* switch sync drive off */ - gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE); -} - -static void gvc1100_muxsel(struct bttv *btv, unsigned int input) -{ - static const int masks[] = {0x30, 0x01, 0x12, 0x23}; - gpio_write(masks[input%4]); -} - -/* LMLBT4x initialization - to allow access to GPIO bits for sensors input and - alarms output - - GPIObit | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - assignment | TI | O3|INx| O2| O1|IN4|IN3|IN2|IN1| | | - - IN - sensor inputs, INx - sensor inputs and TI XORed together - O1,O2,O3 - alarm outputs (relays) - - OUT ENABLE 1 1 0 . 1 1 0 0 . 0 0 0 0 = 0x6C0 - -*/ - -static void init_lmlbt4x(struct bttv *btv) -{ - pr_debug("LMLBT4x init\n"); - btwrite(0x000000, BT848_GPIO_REG_INP); - gpio_inout(0xffffff, 0x0006C0); - gpio_write(0x000000); -} - -static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input) -{ - unsigned int inmux = input % 8; - gpio_inout( 0xf, 0xf ); - gpio_bits( 0xf, inmux ); -} - -static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input) -{ - unsigned int inmux = input % 4; - gpio_inout( 3<<9, 3<<9 ); - gpio_bits( 3<<9, inmux<<9 ); -} - -static void geovision_muxsel(struct bttv *btv, unsigned int input) -{ - unsigned int inmux = input % 16; - gpio_inout(0xf, 0xf); - gpio_bits(0xf, inmux); -} - -/* - * The TD3116 has 2 74HC4051 muxes wired to the MUX0 input of a bt878. - * The first 74HC4051 has the lower 8 inputs, the second one the higher 8. - * The muxes are controlled via a 74HC373 latch which is connected to - * GPIOs 0-7. GPIO 18 is connected to the LE signal of the latch. - * Q0 of the latch is connected to the Enable (~E) input of the first - * 74HC4051. Q1 - Q3 are connected to S0 - S2 of the same 74HC4051. - * Q4 - Q7 are connected to the second 74HC4051 in the same way. - */ - -static void td3116_latch_value(struct bttv *btv, u32 value) -{ - gpio_bits((1<<18) | 0xff, value); - gpio_bits((1<<18) | 0xff, (1<<18) | value); - udelay(1); - gpio_bits((1<<18) | 0xff, value); -} - -static void td3116_muxsel(struct bttv *btv, unsigned int input) -{ - u32 value; - u32 highbit; - - highbit = (input & 0x8) >> 3 ; - - /* Disable outputs and set value in the mux */ - value = 0x11; /* Disable outputs */ - value |= ((input & 0x7) << 1) << (4 * highbit); - td3116_latch_value(btv, value); - - /* Enable the correct output */ - value &= ~0x11; - value |= ((highbit ^ 0x1) << 4) | highbit; - td3116_latch_value(btv, value); -} - -/* ----------------------------------------------------------------------- */ - -static void bttv_reset_audio(struct bttv *btv) -{ - /* - * BT878A has a audio-reset register. - * 1. This register is an audio reset function but it is in - * function-0 (video capture) address space. - * 2. It is enough to do this once per power-up of the card. - * 3. There is a typo in the Conexant doc -- it is not at - * 0x5B, but at 0x058. (B is an odd-number, obviously a typo!). - * --//Shrikumar 030609 - */ - if (btv->id != 878) - return; - - if (bttv_debug) - pr_debug("%d: BT878A ARESET\n", btv->c.nr); - btwrite((1<<7), 0x058); - udelay(10); - btwrite( 0, 0x058); -} - -/* initialization part one -- before registering i2c bus */ -void __devinit bttv_init_card1(struct bttv *btv) -{ - switch (btv->c.type) { - case BTTV_BOARD_HAUPPAUGE: - case BTTV_BOARD_HAUPPAUGE878: - boot_msp34xx(btv,5); - break; - case BTTV_BOARD_VOODOOTV_200: - case BTTV_BOARD_VOODOOTV_FM: - boot_msp34xx(btv,20); - break; - case BTTV_BOARD_AVERMEDIA98: - boot_msp34xx(btv,11); - break; - case BTTV_BOARD_HAUPPAUGEPVR: - pvr_boot(btv); - break; - case BTTV_BOARD_TWINHAN_DST: - case BTTV_BOARD_AVDVBT_771: - case BTTV_BOARD_PINNACLESAT: - btv->use_i2c_hw = 1; - break; - case BTTV_BOARD_ADLINK_RTV24: - init_RTV24( btv ); - break; - - } - if (!bttv_tvcards[btv->c.type].has_dvb) - bttv_reset_audio(btv); -} - -/* initialization part two -- after registering i2c bus */ -void __devinit bttv_init_card2(struct bttv *btv) -{ - btv->tuner_type = UNSET; - - if (BTTV_BOARD_UNKNOWN == btv->c.type) { - bttv_readee(btv,eeprom_data,0xa0); - identify_by_eeprom(btv,eeprom_data); - } - - switch (btv->c.type) { - case BTTV_BOARD_MIRO: - case BTTV_BOARD_MIROPRO: - case BTTV_BOARD_PINNACLE: - case BTTV_BOARD_PINNACLEPRO: - /* miro/pinnacle */ - miro_pinnacle_gpio(btv); - break; - case BTTV_BOARD_FLYVIDEO_98: - case BTTV_BOARD_MAXI: - case BTTV_BOARD_LIFE_FLYKIT: - case BTTV_BOARD_FLYVIDEO: - case BTTV_BOARD_TYPHOON_TVIEW: - case BTTV_BOARD_CHRONOS_VS2: - case BTTV_BOARD_FLYVIDEO_98FM: - case BTTV_BOARD_FLYVIDEO2000: - case BTTV_BOARD_FLYVIDEO98EZ: - case BTTV_BOARD_CONFERENCETV: - case BTTV_BOARD_LIFETEC_9415: - flyvideo_gpio(btv); - break; - case BTTV_BOARD_HAUPPAUGE: - case BTTV_BOARD_HAUPPAUGE878: - case BTTV_BOARD_HAUPPAUGEPVR: - /* pick up some config infos from the eeprom */ - bttv_readee(btv,eeprom_data,0xa0); - hauppauge_eeprom(btv); - break; - case BTTV_BOARD_AVERMEDIA98: - case BTTV_BOARD_AVPHONE98: - bttv_readee(btv,eeprom_data,0xa0); - avermedia_eeprom(btv); - break; - case BTTV_BOARD_PXC200: - init_PXC200(btv); - break; - case BTTV_BOARD_PICOLO_TETRA_CHIP: - picolo_tetra_init(btv); - break; - case BTTV_BOARD_VHX: - btv->has_radio = 1; - btv->has_matchbox = 1; - btv->mbox_we = 0x20; - btv->mbox_most = 0; - btv->mbox_clk = 0x08; - btv->mbox_data = 0x10; - btv->mbox_mask = 0x38; - break; - case BTTV_BOARD_VOBIS_BOOSTAR: - case BTTV_BOARD_TERRATV: - terratec_active_radio_upgrade(btv); - break; - case BTTV_BOARD_MAGICTVIEW061: - if (btv->cardid == 0x3002144f) { - btv->has_radio=1; - pr_info("%d: radio detected by subsystem id (CPH05x)\n", - btv->c.nr); - } - break; - case BTTV_BOARD_STB2: - if (btv->cardid == 0x3060121a) { - /* Fix up entry for 3DFX VoodooTV 100, - which is an OEM STB card variant. */ - btv->has_radio=0; - btv->tuner_type=TUNER_TEMIC_NTSC; - } - break; - case BTTV_BOARD_OSPREY1x0: - case BTTV_BOARD_OSPREY1x0_848: - case BTTV_BOARD_OSPREY101_848: - case BTTV_BOARD_OSPREY1x1: - case BTTV_BOARD_OSPREY1x1_SVID: - case BTTV_BOARD_OSPREY2xx: - case BTTV_BOARD_OSPREY2x0_SVID: - case BTTV_BOARD_OSPREY2x0: - case BTTV_BOARD_OSPREY440: - case BTTV_BOARD_OSPREY500: - case BTTV_BOARD_OSPREY540: - case BTTV_BOARD_OSPREY2000: - bttv_readee(btv,eeprom_data,0xa0); - osprey_eeprom(btv, eeprom_data); - break; - case BTTV_BOARD_IDS_EAGLE: - init_ids_eagle(btv); - break; - case BTTV_BOARD_MODTEC_205: - bttv_readee(btv,eeprom_data,0xa0); - modtec_eeprom(btv); - break; - case BTTV_BOARD_LMLBT4: - init_lmlbt4x(btv); - break; - case BTTV_BOARD_TIBET_CS16: - tibetCS16_init(btv); - break; - case BTTV_BOARD_KODICOM_4400R: - kodicom4400r_init(btv); - break; - case BTTV_BOARD_GEOVISION_GV800S: - gv800s_init(btv); - break; - } - - /* pll configuration */ - if (!(btv->id==848 && btv->revision==0x11)) { - /* defaults from card list */ - if (PLL_28 == bttv_tvcards[btv->c.type].pll) { - btv->pll.pll_ifreq=28636363; - btv->pll.pll_crystal=BT848_IFORM_XT0; - } - if (PLL_35 == bttv_tvcards[btv->c.type].pll) { - btv->pll.pll_ifreq=35468950; - btv->pll.pll_crystal=BT848_IFORM_XT1; - } - /* insmod options can override */ - switch (pll[btv->c.nr]) { - case 0: /* none */ - btv->pll.pll_crystal = 0; - btv->pll.pll_ifreq = 0; - btv->pll.pll_ofreq = 0; - break; - case 1: /* 28 MHz */ - case 28: - btv->pll.pll_ifreq = 28636363; - btv->pll.pll_ofreq = 0; - btv->pll.pll_crystal = BT848_IFORM_XT0; - break; - case 2: /* 35 MHz */ - case 35: - btv->pll.pll_ifreq = 35468950; - btv->pll.pll_ofreq = 0; - btv->pll.pll_crystal = BT848_IFORM_XT1; - break; - } - } - btv->pll.pll_current = -1; - - /* tuner configuration (from card list / autodetect / insmod option) */ - if (UNSET != bttv_tvcards[btv->c.type].tuner_type) - if (UNSET == btv->tuner_type) - btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; - if (UNSET != tuner[btv->c.nr]) - btv->tuner_type = tuner[btv->c.nr]; - - if (btv->tuner_type == TUNER_ABSENT) - pr_info("%d: tuner absent\n", btv->c.nr); - else if (btv->tuner_type == UNSET) - pr_warn("%d: tuner type unset\n", btv->c.nr); - else - pr_info("%d: tuner type=%d\n", btv->c.nr, btv->tuner_type); - - if (autoload != UNSET) { - pr_warn("%d: the autoload option is obsolete\n", btv->c.nr); - pr_warn("%d: use option msp3400, tda7432 or tvaudio to override which audio module should be used\n", - btv->c.nr); - } - - if (UNSET == btv->tuner_type) - btv->tuner_type = TUNER_ABSENT; - - btv->dig = bttv_tvcards[btv->c.type].has_dig_in ? - bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET; - btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? - UNSET : bttv_tvcards[btv->c.type].svhs; - if (svhs[btv->c.nr] != UNSET) - btv->svhs = svhs[btv->c.nr]; - if (remote[btv->c.nr] != UNSET) - btv->has_remote = remote[btv->c.nr]; - - if (bttv_tvcards[btv->c.type].has_radio) - btv->has_radio = 1; - if (bttv_tvcards[btv->c.type].has_remote) - btv->has_remote = 1; - if (!bttv_tvcards[btv->c.type].no_gpioirq) - btv->gpioirq = 1; - if (bttv_tvcards[btv->c.type].volume_gpio) - btv->volume_gpio = bttv_tvcards[btv->c.type].volume_gpio; - if (bttv_tvcards[btv->c.type].audio_mode_gpio) - btv->audio_mode_gpio = bttv_tvcards[btv->c.type].audio_mode_gpio; - - if (btv->tuner_type == TUNER_ABSENT) - return; /* no tuner or related drivers to load */ - - if (btv->has_saa6588 || saa6588[btv->c.nr]) { - /* Probe for RDS receiver chip */ - static const unsigned short addrs[] = { - 0x20 >> 1, - 0x22 >> 1, - I2C_CLIENT_END - }; - struct v4l2_subdev *sd; - - sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "saa6588", 0, addrs); - btv->has_saa6588 = (sd != NULL); - } - - /* try to detect audio/fader chips */ - - /* First check if the user specified the audio chip via a module - option. */ - - switch (audiodev[btv->c.nr]) { - case -1: - return; /* do not load any audio module */ - - case 0: /* autodetect */ - break; - - case 1: { - /* The user specified that we should probe for msp3400 */ - static const unsigned short addrs[] = { - I2C_ADDR_MSP3400 >> 1, - I2C_ADDR_MSP3400_ALT >> 1, - I2C_CLIENT_END - }; - - btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "msp3400", 0, addrs); - if (btv->sd_msp34xx) - return; - goto no_audio; - } - - case 2: { - /* The user specified that we should probe for tda7432 */ - static const unsigned short addrs[] = { - I2C_ADDR_TDA7432 >> 1, - I2C_CLIENT_END - }; - - if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tda7432", 0, addrs)) - return; - goto no_audio; - } - - case 3: { - /* The user specified that we should probe for tvaudio */ - btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); - if (btv->sd_tvaudio) - return; - goto no_audio; - } - - default: - pr_warn("%d: unknown audiodev value!\n", btv->c.nr); - return; - } - - /* There were no overrides, so now we try to discover this through the - card definition */ - - /* probe for msp3400 first: this driver can detect whether or not - it really is a msp3400, so it will return NULL when the device - found is really something else (e.g. a tea6300). */ - if (!bttv_tvcards[btv->c.type].no_msp34xx) { - btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "msp3400", - 0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1)); - } else if (bttv_tvcards[btv->c.type].msp34xx_alt) { - btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "msp3400", - 0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1)); - } - - /* If we found a msp34xx, then we're done. */ - if (btv->sd_msp34xx) - return; - - /* it might also be a tda7432. */ - if (!bttv_tvcards[btv->c.type].no_tda7432) { - static const unsigned short addrs[] = { - I2C_ADDR_TDA7432 >> 1, - I2C_CLIENT_END - }; - - if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tda7432", 0, addrs)) - return; - } - - /* Now see if we can find one of the tvaudio devices. */ - btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); - if (btv->sd_tvaudio) - return; - -no_audio: - pr_warn("%d: audio absent, no audio device found!\n", btv->c.nr); -} - - -/* initialize the tuner */ -void __devinit bttv_init_tuner(struct bttv *btv) -{ - int addr = ADDR_UNSET; - - if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) - addr = bttv_tvcards[btv->c.type].tuner_addr; - - if (btv->tuner_type != TUNER_ABSENT) { - struct tuner_setup tun_setup; - - /* Load tuner module before issuing tuner config call! */ - if (btv->has_radio) - v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tuner", - 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); - v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tuner", - 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); - v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tuner", - 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); - - tun_setup.mode_mask = T_ANALOG_TV; - tun_setup.type = btv->tuner_type; - tun_setup.addr = addr; - - if (btv->has_radio) - tun_setup.mode_mask |= T_RADIO; - - bttv_call_all(btv, tuner, s_type_addr, &tun_setup); - } - - if (btv->tda9887_conf) { - struct v4l2_priv_tun_config tda9887_cfg; - - tda9887_cfg.tuner = TUNER_TDA9887; - tda9887_cfg.priv = &btv->tda9887_conf; - - bttv_call_all(btv, tuner, s_config, &tda9887_cfg); - } -} - -/* ----------------------------------------------------------------------- */ - -static void modtec_eeprom(struct bttv *btv) -{ - if( strncmp(&(eeprom_data[0x1e]),"Temic 4066 FY5",14) ==0) { - btv->tuner_type=TUNER_TEMIC_4066FY5_PAL_I; - pr_info("%d: Modtec: Tuner autodetected by eeprom: %s\n", - btv->c.nr, &eeprom_data[0x1e]); - } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) { - btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; - pr_info("%d: Modtec: Tuner autodetected by eeprom: %s\n", - btv->c.nr, &eeprom_data[0x1e]); - } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) { - btv->tuner_type=TUNER_PHILIPS_NTSC; - pr_info("%d: Modtec: Tuner autodetected by eeprom: %s\n", - btv->c.nr, &eeprom_data[0x1e]); - } else { - pr_info("%d: Modtec: Unknown TunerString: %s\n", - btv->c.nr, &eeprom_data[0x1e]); - } -} - -static void __devinit hauppauge_eeprom(struct bttv *btv) -{ - struct tveeprom tv; - - tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data); - btv->tuner_type = tv.tuner_type; - btv->has_radio = tv.has_radio; - - pr_info("%d: Hauppauge eeprom indicates model#%d\n", - btv->c.nr, tv.model); - - /* - * Some of the 878 boards have duplicate PCI IDs. Switch the board - * type based on model #. - */ - if(tv.model == 64900) { - pr_info("%d: Switching board type from %s to %s\n", - btv->c.nr, - bttv_tvcards[btv->c.type].name, - bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name); - btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB; - } - - /* The 61334 needs the msp3410 to do the radio demod to get sound */ - if (tv.model == 61334) - btv->radio_uses_msp_demodulator = 1; -} - -static int terratec_active_radio_upgrade(struct bttv *btv) -{ - int freq; - - btv->has_radio = 1; - btv->has_matchbox = 1; - btv->mbox_we = 0x10; - btv->mbox_most = 0x20; - btv->mbox_clk = 0x08; - btv->mbox_data = 0x04; - btv->mbox_mask = 0x3c; - - btv->mbox_iow = 1 << 8; - btv->mbox_ior = 1 << 9; - btv->mbox_csel = 1 << 10; - - freq=88000/62.5; - tea5757_write(btv, 5 * freq + 0x358); /* write 0x1ed8 */ - if (0x1ed8 == tea5757_read(btv)) { - pr_info("%d: Terratec Active Radio Upgrade found\n", btv->c.nr); - btv->has_radio = 1; - btv->has_saa6588 = 1; - btv->has_matchbox = 1; - } else { - btv->has_radio = 0; - btv->has_matchbox = 0; - } - return 0; -} - - -/* ----------------------------------------------------------------------- */ - -/* - * minimal bootstrap for the WinTV/PVR -- upload altera firmware. - * - * The hcwamc.rbf firmware file is on the Hauppauge driver CD. Have - * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be - * unpacked with unzip). - */ -#define PVR_GPIO_DELAY 10 - -#define BTTV_ALT_DATA 0x000001 -#define BTTV_ALT_DCLK 0x100000 -#define BTTV_ALT_NCONFIG 0x800000 - -static int __devinit pvr_altera_load(struct bttv *btv, const u8 *micro, - u32 microlen) -{ - u32 n; - u8 bits; - int i; - - gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); - gpio_write(0); - udelay(PVR_GPIO_DELAY); - - gpio_write(BTTV_ALT_NCONFIG); - udelay(PVR_GPIO_DELAY); - - for (n = 0; n < microlen; n++) { - bits = micro[n]; - for (i = 0 ; i < 8 ; i++) { - gpio_bits(BTTV_ALT_DCLK,0); - if (bits & 0x01) - gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA); - else - gpio_bits(BTTV_ALT_DATA,0); - gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK); - bits >>= 1; - } - } - gpio_bits(BTTV_ALT_DCLK,0); - udelay(PVR_GPIO_DELAY); - - /* begin Altera init loop (Not necessary,but doesn't hurt) */ - for (i = 0 ; i < 30 ; i++) { - gpio_bits(BTTV_ALT_DCLK,0); - gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK); - } - gpio_bits(BTTV_ALT_DCLK,0); - return 0; -} - -static int __devinit pvr_boot(struct bttv *btv) -{ - const struct firmware *fw_entry; - int rc; - - rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); - if (rc != 0) { - pr_warn("%d: no altera firmware [via hotplug]\n", btv->c.nr); - return rc; - } - rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); - pr_info("%d: altera firmware upload %s\n", - btv->c.nr, (rc < 0) ? "failed" : "ok"); - release_firmware(fw_entry); - return rc; -} - -/* ----------------------------------------------------------------------- */ -/* some osprey specific stuff */ - -static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256]) -{ - int i; - u32 serial = 0; - int cardid = -1; - - /* This code will nevery actually get called in this case.... */ - if (btv->c.type == BTTV_BOARD_UNKNOWN) { - /* this might be an antique... check for MMAC label in eeprom */ - if (!strncmp(ee, "MMAC", 4)) { - u8 checksum = 0; - for (i = 0; i < 21; i++) - checksum += ee[i]; - if (checksum != ee[21]) - return; - cardid = BTTV_BOARD_OSPREY1x0_848; - for (i = 12; i < 21; i++) - serial *= 10, serial += ee[i] - '0'; - } - } else { - unsigned short type; - - for (i = 4*16; i < 8*16; i += 16) { - u16 checksum = ip_compute_csum(ee + i, 16); - - if ((checksum&0xff) + (checksum>>8) == 0xff) - break; - } - if (i >= 8*16) - return; - ee += i; - - /* found a valid descriptor */ - type = get_unaligned_be16((__be16 *)(ee+4)); - - switch(type) { - /* 848 based */ - case 0x0004: - cardid = BTTV_BOARD_OSPREY1x0_848; - break; - case 0x0005: - cardid = BTTV_BOARD_OSPREY101_848; - break; - - /* 878 based */ - case 0x0012: - case 0x0013: - cardid = BTTV_BOARD_OSPREY1x0; - break; - case 0x0014: - case 0x0015: - cardid = BTTV_BOARD_OSPREY1x1; - break; - case 0x0016: - case 0x0017: - case 0x0020: - cardid = BTTV_BOARD_OSPREY1x1_SVID; - break; - case 0x0018: - case 0x0019: - case 0x001E: - case 0x001F: - cardid = BTTV_BOARD_OSPREY2xx; - break; - case 0x001A: - case 0x001B: - cardid = BTTV_BOARD_OSPREY2x0_SVID; - break; - case 0x0040: - cardid = BTTV_BOARD_OSPREY500; - break; - case 0x0050: - case 0x0056: - cardid = BTTV_BOARD_OSPREY540; - /* bttv_osprey_540_init(btv); */ - break; - case 0x0060: - case 0x0070: - case 0x00A0: - cardid = BTTV_BOARD_OSPREY2x0; - /* enable output on select control lines */ - gpio_inout(0xffffff,0x000303); - break; - case 0x00D8: - cardid = BTTV_BOARD_OSPREY440; - break; - default: - /* unknown...leave generic, but get serial # */ - pr_info("%d: osprey eeprom: unknown card type 0x%04x\n", - btv->c.nr, type); - break; - } - serial = get_unaligned_be32((__be32 *)(ee+6)); - } - - pr_info("%d: osprey eeprom: card=%d '%s' serial=%u\n", - btv->c.nr, cardid, - cardid > 0 ? bttv_tvcards[cardid].name : "Unknown", serial); - - if (cardid<0 || btv->c.type == cardid) - return; - - /* card type isn't set correctly */ - if (card[btv->c.nr] < bttv_num_tvcards) { - pr_warn("%d: osprey eeprom: Not overriding user specified card type\n", - btv->c.nr); - } else { - pr_info("%d: osprey eeprom: Changing card type from %d to %d\n", - btv->c.nr, btv->c.type, cardid); - btv->c.type = cardid; - } -} - -/* ----------------------------------------------------------------------- */ -/* AVermedia specific stuff, from bktr_card.c */ - -static int tuner_0_table[] = { - TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/, - TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/, - TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, - TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, - TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL, - TUNER_PHILIPS_FM1216ME_MK3 }; - -static int tuner_1_table[] = { - TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, - TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, - TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, - TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */ - TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL}; - -static void __devinit avermedia_eeprom(struct bttv *btv) -{ - int tuner_make, tuner_tv_fm, tuner_format, tuner_type = 0; - - tuner_make = (eeprom_data[0x41] & 0x7); - tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; - tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; - btv->has_remote = (eeprom_data[0x42] & 0x01); - - if (tuner_make == 0 || tuner_make == 2) - if (tuner_format <= 0x0a) - tuner_type = tuner_0_table[tuner_format]; - if (tuner_make == 1) - if (tuner_format <= 9) - tuner_type = tuner_1_table[tuner_format]; - - if (tuner_make == 4) - if (tuner_format == 0x09) - tuner_type = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */ - - pr_info("%d: Avermedia eeprom[0x%02x%02x]: tuner=", - btv->c.nr, eeprom_data[0x41], eeprom_data[0x42]); - if (tuner_type) { - btv->tuner_type = tuner_type; - pr_cont("%d", tuner_type); - } else - pr_cont("Unknown type"); - pr_cont(" radio:%s remote control:%s\n", - tuner_tv_fm ? "yes" : "no", - btv->has_remote ? "yes" : "no"); -} - -/* - * For Voodoo TV/FM and Voodoo 200. These cards' tuners use a TDA9880 - * analog demod, which is not I2C controlled like the newer and more common - * TDA9887 series. Instead is has two tri-state input pins, S0 and S1, - * that control the IF for the video and audio. Apparently, bttv GPIO - * 0x10000 is connected to S0. S0 low selects a 38.9 MHz VIF for B/G/D/K/I - * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC). - */ -u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits) -{ - - if (btv->audio == TVAUDIO_INPUT_TUNER) { - if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN) - gpiobits |= 0x10000; - else - gpiobits &= ~0x10000; - } - - gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpiobits); - return gpiobits; -} - - -/* - * reset/enable the MSP on some Hauppauge cards - * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! - * - * Hauppauge: pin 5 - * Voodoo: pin 20 - */ -static void __devinit boot_msp34xx(struct bttv *btv, int pin) -{ - int mask = (1 << pin); - - gpio_inout(mask,mask); - gpio_bits(mask,0); - mdelay(2); - udelay(500); - gpio_bits(mask,mask); - - if (bttv_gpio) - bttv_gpio_tracking(btv,"msp34xx"); - if (bttv_verbose) - pr_info("%d: Hauppauge/Voodoo msp34xx: reset line init [%d]\n", - btv->c.nr, pin); -} - -/* ----------------------------------------------------------------------- */ -/* Imagenation L-Model PXC200 Framegrabber */ -/* This is basically the same procedure as - * used by Alessandro Rubini in his pxc200 - * driver, but using BTTV functions */ - -static void __devinit init_PXC200(struct bttv *btv) -{ - static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x00 }; - unsigned int i; - int tmp; - u32 val; - - /* Initialise GPIO-connevted stuff */ - gpio_inout(0xffffff, (1<<13)); - gpio_write(0); - udelay(3); - gpio_write(1<<13); - /* GPIO inputs are pulled up, so no need to drive - * reset pin any longer */ - gpio_bits(0xffffff, 0); - if (bttv_gpio) - bttv_gpio_tracking(btv,"pxc200"); - - /* we could/should try and reset/control the AD pots? but - right now we simply turned off the crushing. Without - this the AGC drifts drifts - remember the EN is reverse logic --> - setting BT848_ADC_AGC_EN disable the AGC - tboult@eecs.lehigh.edu - */ - - btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC); - - /* Initialise MAX517 DAC */ - pr_info("Setting DAC reference voltage level ...\n"); - bttv_I2CWrite(btv,0x5E,0,0x80,1); - - /* Initialise 12C508 PIC */ - /* The I2CWrite and I2CRead commmands are actually to the - * same chips - but the R/W bit is included in the address - * argument so the numbers are different */ - - - pr_info("Initialising 12C508 PIC chip ...\n"); - - /* First of all, enable the clock line. This is used in the PXC200-F */ - val = btread(BT848_GPIO_DMA_CTL); - val |= BT848_GPIO_DMA_CTL_GPCLKMODE; - btwrite(val, BT848_GPIO_DMA_CTL); - - /* Then, push to 0 the reset pin long enough to reset the * - * device same as above for the reset line, but not the same - * value sent to the GPIO-connected stuff - * which one is the good one? */ - gpio_inout(0xffffff,(1<<2)); - gpio_write(0); - udelay(10); - gpio_write(1<<2); - - for (i = 0; i < ARRAY_SIZE(vals); i++) { - tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); - if (tmp != -1) { - pr_info("I2C Write(%2.2x) = %i\nI2C Read () = %2.2x\n\n", - vals[i],tmp,bttv_I2CRead(btv,0x1F,NULL)); - } - } - - pr_info("PXC200 Initialised\n"); -} - - - -/* ----------------------------------------------------------------------- */ -/* - * The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock - * it. This apparently involves the following procedure for each 878 chip: - * - * 1) write 0x00C3FEFF to the GPIO_OUT_EN register - * - * 2) write to GPIO_DATA - * - 0x0E - * - sleep 1ms - * - 0x10 + 0x0E - * - sleep 10ms - * - 0x0E - * read from GPIO_DATA into buf (uint_32) - * - if ( data>>18 & 0x01 != 0) || ( buf>>19 & 0x01 != 1 ) - * error. ERROR_CPLD_Check_Failed stop. - * - * 3) write to GPIO_DATA - * - write 0x4400 + 0x0E - * - sleep 10ms - * - write 0x4410 + 0x0E - * - sleep 1ms - * - write 0x0E - * read from GPIO_DATA into buf (uint_32) - * - if ( buf>>18 & 0x01 ) || ( buf>>19 & 0x01 != 0 ) - * error. ERROR_CPLD_Check_Failed. - */ -/* ----------------------------------------------------------------------- */ -static void -init_RTV24 (struct bttv *btv) -{ - uint32_t dataRead = 0; - long watchdog_value = 0x0E; - - pr_info("%d: Adlink RTV-24 initialisation in progress ...\n", - btv->c.nr); - - btwrite (0x00c3feff, BT848_GPIO_OUT_EN); - - btwrite (0 + watchdog_value, BT848_GPIO_DATA); - msleep (1); - btwrite (0x10 + watchdog_value, BT848_GPIO_DATA); - msleep (10); - btwrite (0 + watchdog_value, BT848_GPIO_DATA); - - dataRead = btread (BT848_GPIO_DATA); - - if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 1)) { - pr_info("%d: Adlink RTV-24 initialisation(1) ERROR_CPLD_Check_Failed (read %d)\n", - btv->c.nr, dataRead); - } - - btwrite (0x4400 + watchdog_value, BT848_GPIO_DATA); - msleep (10); - btwrite (0x4410 + watchdog_value, BT848_GPIO_DATA); - msleep (1); - btwrite (watchdog_value, BT848_GPIO_DATA); - msleep (1); - dataRead = btread (BT848_GPIO_DATA); - - if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 0)) { - pr_info("%d: Adlink RTV-24 initialisation(2) ERROR_CPLD_Check_Failed (read %d)\n", - btv->c.nr, dataRead); - - return; - } - - pr_info("%d: Adlink RTV-24 initialisation complete\n", btv->c.nr); -} - - - -/* ----------------------------------------------------------------------- */ -/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */ -/* - * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu> - * This code is placed under the terms of the GNU General Public License - * - * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00 - */ - -static void bus_low(struct bttv *btv, int bit) -{ - if (btv->mbox_ior) { - gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); - udelay(5); - } - - gpio_bits(bit,0); - udelay(5); - - if (btv->mbox_ior) { - gpio_bits(btv->mbox_iow | btv->mbox_csel, 0); - udelay(5); - } -} - -static void bus_high(struct bttv *btv, int bit) -{ - if (btv->mbox_ior) { - gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); - udelay(5); - } - - gpio_bits(bit,bit); - udelay(5); - - if (btv->mbox_ior) { - gpio_bits(btv->mbox_iow | btv->mbox_csel, 0); - udelay(5); - } -} - -static int bus_in(struct bttv *btv, int bit) -{ - if (btv->mbox_ior) { - gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); - udelay(5); - - gpio_bits(btv->mbox_iow | btv->mbox_csel, 0); - udelay(5); - } - return gpio_read() & (bit); -} - -/* TEA5757 register bits */ -#define TEA_FREQ 0:14 -#define TEA_BUFFER 15:15 - -#define TEA_SIGNAL_STRENGTH 16:17 - -#define TEA_PORT1 18:18 -#define TEA_PORT0 19:19 - -#define TEA_BAND 20:21 -#define TEA_BAND_FM 0 -#define TEA_BAND_MW 1 -#define TEA_BAND_LW 2 -#define TEA_BAND_SW 3 - -#define TEA_MONO 22:22 -#define TEA_ALLOW_STEREO 0 -#define TEA_FORCE_MONO 1 - -#define TEA_SEARCH_DIRECTION 23:23 -#define TEA_SEARCH_DOWN 0 -#define TEA_SEARCH_UP 1 - -#define TEA_STATUS 24:24 -#define TEA_STATUS_TUNED 0 -#define TEA_STATUS_SEARCHING 1 - -/* Low-level stuff */ -static int tea5757_read(struct bttv *btv) -{ - unsigned long timeout; - int value = 0; - int i; - - /* better safe than sorry */ - gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we); - - if (btv->mbox_ior) { - gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); - udelay(5); - } - - if (bttv_gpio) - bttv_gpio_tracking(btv,"tea5757 read"); - - bus_low(btv,btv->mbox_we); - bus_low(btv,btv->mbox_clk); - - udelay(10); - timeout= jiffies + msecs_to_jiffies(1000); - - /* wait for DATA line to go low; error if it doesn't */ - while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout)) - schedule(); - if (bus_in(btv,btv->mbox_data)) { - pr_warn("%d: tea5757: read timeout\n", btv->c.nr); - return -1; - } - - dprintk("%d: tea5757:", btv->c.nr); - for (i = 0; i < 24; i++) { - udelay(5); - bus_high(btv,btv->mbox_clk); - udelay(5); - dprintk_cont("%c", - bus_in(btv, btv->mbox_most) == 0 ? 'T' : '-'); - bus_low(btv,btv->mbox_clk); - value <<= 1; - value |= (bus_in(btv,btv->mbox_data) == 0)?0:1; /* MSB first */ - dprintk_cont("%c", - bus_in(btv, btv->mbox_most) == 0 ? 'S' : 'M'); - } - dprintk_cont("\n"); - dprintk("%d: tea5757: read 0x%X\n", btv->c.nr, value); - return value; -} - -static int tea5757_write(struct bttv *btv, int value) -{ - int i; - int reg = value; - - gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we | btv->mbox_data); - - if (btv->mbox_ior) { - gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); - udelay(5); - } - if (bttv_gpio) - bttv_gpio_tracking(btv,"tea5757 write"); - - dprintk("%d: tea5757: write 0x%X\n", btv->c.nr, value); - bus_low(btv,btv->mbox_clk); - bus_high(btv,btv->mbox_we); - for (i = 0; i < 25; i++) { - if (reg & 0x1000000) - bus_high(btv,btv->mbox_data); - else - bus_low(btv,btv->mbox_data); - reg <<= 1; - bus_high(btv,btv->mbox_clk); - udelay(10); - bus_low(btv,btv->mbox_clk); - udelay(10); - } - bus_low(btv,btv->mbox_we); /* unmute !!! */ - return 0; -} - -void tea5757_set_freq(struct bttv *btv, unsigned short freq) -{ - dprintk("tea5757_set_freq %d\n",freq); - tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */ -} - -/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas] - * - * This is needed because rv605 don't use a normal multiplex, but a crosspoint - * switch instead (CD22M3494E). This IC can have multiple active connections - * between Xn (input) and Yn (output) pins. We need to clear any existing - * connection prior to establish a new one, pulsing the STROBE pin. - * - * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin. - * GPIO pins are wired as: - * GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroller) - * GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroller) - * GPIO[7] - DATA (xpoint) - P1[7] (microcontroller) - * GPIO[8] - - P3[5] (microcontroller) - * GPIO[9] - RESET (xpoint) - P3[6] (microcontroller) - * GPIO[10] - STROBE (xpoint) - P3[7] (microcontroller) - * GPINTR - - P3[4] (microcontroller) - * - * The microcontroller is a 80C32 like. It should be possible to change xpoint - * configuration either directly (as we are doing) or using the microcontroller - * which is also wired to I2C interface. I have no further info on the - * microcontroller features, one would need to disassembly the firmware. - * note: the vendor refused to give any information on this product, all - * that stuff was found using a multimeter! :) - */ -static void rv605_muxsel(struct bttv *btv, unsigned int input) -{ - static const u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0, - 0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa }; - - gpio_bits(0x07f, muxgpio[input]); - - /* reset all conections */ - gpio_bits(0x200,0x200); - mdelay(1); - gpio_bits(0x200,0x000); - mdelay(1); - - /* create a new connection */ - gpio_bits(0x480,0x480); - mdelay(1); - gpio_bits(0x480,0x080); - mdelay(1); -} - -/* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning] - * - * The CS16 (available on eBay cheap) is a PCI board with four Fusion - * 878A chips, a PCI bridge, an Atmel microcontroller, four sync separator - * chips, ten eight input analog multiplexors, a not chip and a few - * other components. - * - * 16 inputs on a secondary bracket are provided and can be selected - * from each of the four capture chips. Two of the eight input - * multiplexors are used to select from any of the 16 input signals. - * - * Unsupported hardware capabilities: - * . A video output monitor on the secondary bracket can be selected from - * one of the 878A chips. - * . Another passthrough but I haven't spent any time investigating it. - * . Digital I/O (logic level connected to GPIO) is available from an - * onboard header. - * - * The on chip input mux should always be set to 2. - * GPIO[16:19] - Video input selection - * GPIO[0:3] - Video output monitor select (only available from one 878A) - * GPIO[?:?] - Digital I/O. - * - * There is an ATMEL microcontroller with an 8031 core on board. I have not - * determined what function (if any) it provides. With the microcontroller - * and sync separator chips a guess is that it might have to do with video - * switching and maybe some digital I/O. - */ -static void tibetCS16_muxsel(struct bttv *btv, unsigned int input) -{ - /* video mux */ - gpio_bits(0x0f0000, input << 16); -} - -static void tibetCS16_init(struct bttv *btv) -{ - /* enable gpio bits, mask obtained via btSpy */ - gpio_inout(0xffffff, 0x0f7fff); - gpio_write(0x0f7fff); -} - -/* - * The following routines for the Kodicom-4400r get a little mind-twisting. - * There is a "master" controller and three "slave" controllers, together - * an analog switch which connects any of 16 cameras to any of the BT87A's. - * The analog switch is controlled by the "master", but the detection order - * of the four BT878A chips is in an order which I just don't understand. - * The "master" is actually the second controller to be detected. The - * logic on the board uses logical numbers for the 4 controllers, but - * those numbers are different from the detection sequence. When working - * with the analog switch, we need to "map" from the detection sequence - * over to the board's logical controller number. This mapping sequence - * is {3, 0, 2, 1}, i.e. the first controller to be detected is logical - * unit 3, the second (which is the master) is logical unit 0, etc. - * We need to maintain the status of the analog switch (which of the 16 - * cameras is connected to which of the 4 controllers). Rather than - * add to the bttv structure for this, we use the data reserved for - * the mbox (unused for this card type). - */ - -/* - * First a routine to set the analog switch, which controls which camera - * is routed to which controller. The switch comprises an X-address - * (gpio bits 0-3, representing the camera, ranging from 0-15), and a - * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3). - * A data value (gpio bit 7) of '1' enables the switch, and '0' disables - * the switch. A STROBE bit (gpio bit 8) latches the data value into the - * specified address. The idea is to set the address and data, then bring - * STROBE high, and finally bring STROBE back to low. - */ -static void kodicom4400r_write(struct bttv *btv, - unsigned char xaddr, - unsigned char yaddr, - unsigned char data) { - unsigned int udata; - - udata = (data << 7) | ((yaddr&3) << 4) | (xaddr&0xf); - gpio_bits(0x1ff, udata); /* write ADDR and DAT */ - gpio_bits(0x1ff, udata | (1 << 8)); /* strobe high */ - gpio_bits(0x1ff, udata); /* strobe low */ -} - -/* - * Next the mux select. Both the "master" and "slave" 'cards' (controllers) - * use this routine. The routine finds the "master" for the card, maps - * the controller number from the detected position over to the logical - * number, writes the appropriate data to the analog switch, and housekeeps - * the local copy of the switch information. The parameter 'input' is the - * requested camera number (0 - 15). - */ -static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input) -{ - char *sw_status; - int xaddr, yaddr; - struct bttv *mctlr; - static unsigned char map[4] = {3, 0, 2, 1}; - - mctlr = master[btv->c.nr]; - if (mctlr == NULL) { /* ignore if master not yet detected */ - return; - } - yaddr = (btv->c.nr - mctlr->c.nr + 1) & 3; /* the '&' is for safety */ - yaddr = map[yaddr]; - sw_status = (char *)(&mctlr->mbox_we); - xaddr = input & 0xf; - /* Check if the controller/camera pair has changed, else ignore */ - if (sw_status[yaddr] != xaddr) - { - /* "open" the old switch, "close" the new one, save the new */ - kodicom4400r_write(mctlr, sw_status[yaddr], yaddr, 0); - sw_status[yaddr] = xaddr; - kodicom4400r_write(mctlr, xaddr, yaddr, 1); - } -} - -/* - * During initialisation, we need to reset the analog switch. We - * also preset the switch to map the 4 connectors on the card to the - * *user's* (see above description of kodicom4400r_muxsel) channels - * 0 through 3 - */ -static void kodicom4400r_init(struct bttv *btv) -{ - char *sw_status = (char *)(&btv->mbox_we); - int ix; - - gpio_inout(0x0003ff, 0x0003ff); - gpio_write(1 << 9); /* reset MUX */ - gpio_write(0); - /* Preset camera 0 to the 4 controllers */ - for (ix = 0; ix < 4; ix++) { - sw_status[ix] = ix; - kodicom4400r_write(btv, ix, ix, 1); - } - /* - * Since this is the "master", we need to set up the - * other three controller chips' pointers to this structure - * for later use in the muxsel routine. - */ - if ((btv->c.nr<1) || (btv->c.nr>BTTV_MAX-3)) - return; - master[btv->c.nr-1] = btv; - master[btv->c.nr] = btv; - master[btv->c.nr+1] = btv; - master[btv->c.nr+2] = btv; -} - -/* The Grandtec X-Guard framegrabber card uses two Dual 4-channel - * video multiplexers to provide up to 16 video inputs. These - * multiplexers are controlled by the lower 8 GPIO pins of the - * bt878. The multiplexers probably Pericom PI5V331Q or similar. - - * xxx0 is pin xxx of multiplexer U5, - * yyy1 is pin yyy of multiplexer U2 - */ -#define ENA0 0x01 -#define ENB0 0x02 -#define ENA1 0x04 -#define ENB1 0x08 - -#define IN10 0x10 -#define IN00 0x20 -#define IN11 0x40 -#define IN01 0x80 - -static void xguard_muxsel(struct bttv *btv, unsigned int input) -{ - static const int masks[] = { - ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10, - ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10, - ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, - ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, - }; - gpio_write(masks[input%16]); -} -static void picolo_tetra_init(struct bttv *btv) -{ - /*This is the video input redirection fonctionality : I DID NOT USED IT. */ - btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */ - btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A] set to 1*/ -} -static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input) -{ - - dprintk("%d : picolo_tetra_muxsel => input = %d\n", btv->c.nr, input); - /*Just set the right path in the analog multiplexers : channel 1 -> 4 ==> Analog Mux ==> MUX0*/ - /*GPIO[20]&GPIO[21] used to choose the right input*/ - btwrite (input<<20,BT848_GPIO_DATA); - -} - -/* - * ivc120_muxsel [Added by Alan Garfield <alan@fromorbit.com>] - * - * The IVC120G security card has 4 i2c controlled TDA8540 matrix - * swichers to provide 16 channels to MUX0. The TDA8540's have - * 4 independent outputs and as such the IVC120G also has the - * optional "Monitor Out" bus. This allows the card to be looking - * at one input while the monitor is looking at another. - * - * Since I've couldn't be bothered figuring out how to add an - * independent muxsel for the monitor bus, I've just set it to - * whatever the card is looking at. - * - * OUT0 of the TDA8540's is connected to MUX0 (0x03) - * OUT1 of the TDA8540's is connected to "Monitor Out" (0x0C) - * - * TDA8540_ALT3 IN0-3 = Channel 13 - 16 (0x03) - * TDA8540_ALT4 IN0-3 = Channel 1 - 4 (0x03) - * TDA8540_ALT5 IN0-3 = Channel 5 - 8 (0x03) - * TDA8540_ALT6 IN0-3 = Channel 9 - 12 (0x03) - * - */ - -/* All 7 possible sub-ids for the TDA8540 Matrix Switcher */ -#define I2C_TDA8540 0x90 -#define I2C_TDA8540_ALT1 0x92 -#define I2C_TDA8540_ALT2 0x94 -#define I2C_TDA8540_ALT3 0x96 -#define I2C_TDA8540_ALT4 0x98 -#define I2C_TDA8540_ALT5 0x9a -#define I2C_TDA8540_ALT6 0x9c - -static void ivc120_muxsel(struct bttv *btv, unsigned int input) -{ - /* Simple maths */ - int key = input % 4; - int matrix = input / 4; - - dprintk("%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n", - btv->c.nr, input, matrix, key); - - /* Handles the input selection on the TDA8540's */ - bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00, - ((matrix == 3) ? (key | key << 2) : 0x00), 1); - bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x00, - ((matrix == 0) ? (key | key << 2) : 0x00), 1); - bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x00, - ((matrix == 1) ? (key | key << 2) : 0x00), 1); - bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00, - ((matrix == 2) ? (key | key << 2) : 0x00), 1); - - /* Handles the output enables on the TDA8540's */ - bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02, - ((matrix == 3) ? 0x03 : 0x00), 1); /* 13 - 16 */ - bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02, - ((matrix == 0) ? 0x03 : 0x00), 1); /* 1-4 */ - bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02, - ((matrix == 1) ? 0x03 : 0x00), 1); /* 5-8 */ - bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02, - ((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */ - - /* 878's MUX0 is already selected for input via muxsel values */ -} - - -/* PXC200 muxsel helper - * luke@syseng.anu.edu.au - * another transplant - * from Alessandro Rubini (rubini@linux.it) - * - * There are 4 kinds of cards: - * PXC200L which is bt848 - * PXC200F which is bt848 with PIC controlling mux - * PXC200AL which is bt878 - * PXC200AF which is bt878 with PIC controlling mux - */ -#define PX_CFG_PXC200F 0x01 -#define PX_FLAG_PXC200A 0x00001000 /* a pxc200A is bt-878 based */ -#define PX_I2C_PIC 0x0f -#define PX_PXC200A_CARDID 0x200a1295 -#define PX_I2C_CMD_CFG 0x00 - -static void PXC200_muxsel(struct bttv *btv, unsigned int input) -{ - int rc; - long mux; - int bitmask; - unsigned char buf[2]; - - /* Read PIC config to determine if this is a PXC200F */ - /* PX_I2C_CMD_CFG*/ - buf[0]=0; - buf[1]=0; - rc=bttv_I2CWrite(btv,(PX_I2C_PIC<<1),buf[0],buf[1],1); - if (rc) { - pr_debug("%d: PXC200_muxsel: pic cfg write failed:%d\n", - btv->c.nr, rc); - /* not PXC ? do nothing */ - return; - } - - rc=bttv_I2CRead(btv,(PX_I2C_PIC<<1),NULL); - if (!(rc & PX_CFG_PXC200F)) { - pr_debug("%d: PXC200_muxsel: not PXC200F rc:%d\n", - btv->c.nr, rc); - return; - } - - - /* The multiplexer in the 200F is handled by the GPIO port */ - /* get correct mapping between inputs */ - /* mux = bttv_tvcards[btv->type].muxsel[input] & 3; */ - /* ** not needed!? */ - mux = input; - - /* make sure output pins are enabled */ - /* bitmask=0x30f; */ - bitmask=0x302; - /* check whether we have a PXC200A */ - if (btv->cardid == PX_PXC200A_CARDID) { - bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ - bitmask |= 7<<4; /* the DAC */ - } - btwrite(bitmask, BT848_GPIO_OUT_EN); - - bitmask = btread(BT848_GPIO_DATA); - if (btv->cardid == PX_PXC200A_CARDID) - bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); - else /* older device */ - bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); - btwrite(bitmask,BT848_GPIO_DATA); - - /* - * Was "to be safe, set the bt848 to input 0" - * Actually, since it's ok at load time, better not messing - * with these bits (on PXC200AF you need to set mux 2 here) - * - * needed because bttv-driver sets mux before calling this function - */ - if (btv->cardid == PX_PXC200A_CARDID) - btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); - else /* older device */ - btand(~BT848_IFORM_MUXSEL,BT848_IFORM); - - pr_debug("%d: setting input channel to:%d\n", btv->c.nr, (int)mux); -} - -static void phytec_muxsel(struct bttv *btv, unsigned int input) -{ - unsigned int mux = input % 4; - - if (input == btv->svhs) - mux = 0; - - gpio_bits(0x3, mux); -} - -/* - * GeoVision GV-800(S) functions - * Bruno Christo <bchristo@inf.ufsm.br> -*/ - -/* This is a function to control the analog switch, which determines which - * camera is routed to which controller. The switch comprises an X-address - * (gpio bits 0-3, representing the camera, ranging from 0-15), and a - * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3). - * A data value (gpio bit 18) of '1' enables the switch, and '0' disables - * the switch. A STROBE bit (gpio bit 17) latches the data value into the - * specified address. There is also a chip select (gpio bit 16). - * The idea is to set the address and chip select together, bring - * STROBE high, write the data, and finally bring STROBE back to low. - */ -static void gv800s_write(struct bttv *btv, - unsigned char xaddr, - unsigned char yaddr, - unsigned char data) { - /* On the "master" 878A: - * GPIO bits 0-9 are used for the analog switch: - * 00 - 03: camera selector - * 04 - 06: 878A (controller) selector - * 16: cselect - * 17: strobe - * 18: data (1->on, 0->off) - * 19: reset - */ - const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4); - const u32 CSELECT = 1<<16; - const u32 STROBE = 1<<17; - const u32 DATA = data<<18; - - gpio_bits(0x1007f, ADDRESS | CSELECT); /* write ADDRESS and CSELECT */ - gpio_bits(0x20000, STROBE); /* STROBE high */ - gpio_bits(0x40000, DATA); /* write DATA */ - gpio_bits(0x20000, ~STROBE); /* STROBE low */ -} - -/* - * GeoVision GV-800(S) muxsel - * - * Each of the 4 cards (controllers) use this function. - * The controller using this function selects the input through the GPIO pins - * of the "master" card. A pointer to this card is stored in master[btv->c.nr]. - * - * The parameter 'input' is the requested camera number (0-4) on the controller. - * The map array has the address of each input. Note that the addresses in the - * array are in the sequence the original GeoVision driver uses, that is, set - * every controller to input 0, then to input 1, 2, 3, repeat. This means that - * the physical "camera 1" connector corresponds to controller 0 input 0, - * "camera 2" corresponds to controller 1 input 0, and so on. - * - * After getting the input address, the function then writes the appropriate - * data to the analog switch, and housekeeps the local copy of the switch - * information. - */ -static void gv800s_muxsel(struct bttv *btv, unsigned int input) -{ - struct bttv *mctlr; - char *sw_status; - int xaddr, yaddr; - static unsigned int map[4][4] = { { 0x0, 0x4, 0xa, 0x6 }, - { 0x1, 0x5, 0xb, 0x7 }, - { 0x2, 0x8, 0xc, 0xe }, - { 0x3, 0x9, 0xd, 0xf } }; - input = input%4; - mctlr = master[btv->c.nr]; - if (mctlr == NULL) { - /* do nothing until the "master" is detected */ - return; - } - yaddr = (btv->c.nr - mctlr->c.nr) & 3; - sw_status = (char *)(&mctlr->mbox_we); - xaddr = map[yaddr][input] & 0xf; - - /* Check if the controller/camera pair has changed, ignore otherwise */ - if (sw_status[yaddr] != xaddr) { - /* disable the old switch, enable the new one and save status */ - gv800s_write(mctlr, sw_status[yaddr], yaddr, 0); - sw_status[yaddr] = xaddr; - gv800s_write(mctlr, xaddr, yaddr, 1); - } -} - -/* GeoVision GV-800(S) "master" chip init */ -static void gv800s_init(struct bttv *btv) -{ - char *sw_status = (char *)(&btv->mbox_we); - int ix; - - gpio_inout(0xf107f, 0xf107f); - gpio_write(1<<19); /* reset the analog MUX */ - gpio_write(0); - - /* Preset camera 0 to the 4 controllers */ - for (ix = 0; ix < 4; ix++) { - sw_status[ix] = ix; - gv800s_write(btv, ix, ix, 1); - } - - /* Inputs on the "master" controller need this brightness fix */ - bttv_I2CWrite(btv, 0x18, 0x5, 0x90, 1); - - if (btv->c.nr > BTTV_MAX-4) - return; - /* - * Store the "master" controller pointer in the master - * array for later use in the muxsel function. - */ - master[btv->c.nr] = btv; - master[btv->c.nr+1] = btv; - master[btv->c.nr+2] = btv; - master[btv->c.nr+3] = btv; -} - -/* ----------------------------------------------------------------------- */ -/* motherboard chipset specific stuff */ - -void __init bttv_check_chipset(void) -{ - int pcipci_fail = 0; - struct pci_dev *dev = NULL; - - if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) /* should check if target is AGP */ - pcipci_fail = 1; - if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF)) - triton1 = 1; - if (pci_pci_problems & PCIPCI_VSFX) - vsfx = 1; -#ifdef PCIPCI_ALIMAGIK - if (pci_pci_problems & PCIPCI_ALIMAGIK) - latency = 0x0A; -#endif - - - /* print warnings about any quirks found */ - if (triton1) - pr_info("Host bridge needs ETBF enabled\n"); - if (vsfx) - pr_info("Host bridge needs VSFX enabled\n"); - if (pcipci_fail) { - pr_info("bttv and your chipset may not work together\n"); - if (!no_overlay) { - pr_info("overlay will be disabled\n"); - no_overlay = 1; - } else { - pr_info("overlay forced. Use this option at your own risk.\n"); - } - } - if (UNSET != latency) - pr_info("pci latency fixup [%d]\n", latency); - while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82441, dev))) { - unsigned char b; - pci_read_config_byte(dev, 0x53, &b); - if (bttv_debug) - pr_info("Host bridge: 82441FX Natoma, bufcon=0x%02x\n", - b); - } -} - -int __devinit bttv_handle_chipset(struct bttv *btv) -{ - unsigned char command; - - if (!triton1 && !vsfx && UNSET == latency) - return 0; - - if (bttv_verbose) { - if (triton1) - pr_info("%d: enabling ETBF (430FX/VP3 compatibility)\n", - btv->c.nr); - if (vsfx && btv->id >= 878) - pr_info("%d: enabling VSFX\n", btv->c.nr); - if (UNSET != latency) - pr_info("%d: setting pci timer to %d\n", - btv->c.nr, latency); - } - - if (btv->id < 878) { - /* bt848 (mis)uses a bit in the irq mask for etbf */ - if (triton1) - btv->triton1 = BT848_INT_ETBF; - } else { - /* bt878 has a bit in the pci config space for it */ - pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command); - if (triton1) - command |= BT878_EN_TBFX; - if (vsfx) - command |= BT878_EN_VSFX; - pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command); - } - if (UNSET != latency) - pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); - return 0; -} - - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c deleted file mode 100644 index b58ff87db771..000000000000 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ /dev/null @@ -1,4630 +0,0 @@ -/* - - bttv - Bt848 frame grabber driver - - Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de> - & Marcus Metzler <mocm@thp.uni-koeln.de> - (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org> - - some v4l2 code lines are taken from Justin's bttv2 driver which is - (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za> - - V4L1 removal from: - (c) 2005-2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru> - - Fixes to be fully V4L2 compliant by - (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> - - Cropping and overscan support - Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> - Sponsored by OPQ Systems AB - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/kdev_t.h> -#include "bttvp.h" -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include <media/tvaudio.h> -#include <media/msp3400.h> - -#include <linux/dma-mapping.h> - -#include <asm/io.h> -#include <asm/byteorder.h> - -#include <media/saa6588.h> - -#define BTTV_VERSION "0.9.19" - -unsigned int bttv_num; /* number of Bt848s in use */ -struct bttv *bttvs[BTTV_MAX]; - -unsigned int bttv_debug; -unsigned int bttv_verbose = 1; -unsigned int bttv_gpio; - -/* config variables */ -#ifdef __BIG_ENDIAN -static unsigned int bigendian=1; -#else -static unsigned int bigendian; -#endif -static unsigned int radio[BTTV_MAX]; -static unsigned int irq_debug; -static unsigned int gbuffers = 8; -static unsigned int gbufsize = 0x208000; -static unsigned int reset_crop = 1; - -static int video_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; -static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; -static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; -static int debug_latency; -static int disable_ir; - -static unsigned int fdsr; - -/* options */ -static unsigned int combfilter; -static unsigned int lumafilter; -static unsigned int automute = 1; -static unsigned int chroma_agc; -static unsigned int adc_crush = 1; -static unsigned int whitecrush_upper = 0xCF; -static unsigned int whitecrush_lower = 0x7F; -static unsigned int vcr_hack; -static unsigned int irq_iswitch; -static unsigned int uv_ratio = 50; -static unsigned int full_luma_range; -static unsigned int coring; - -/* API features (turn on/off stuff for testing) */ -static unsigned int v4l2 = 1; - -/* insmod args */ -module_param(bttv_verbose, int, 0644); -module_param(bttv_gpio, int, 0644); -module_param(bttv_debug, int, 0644); -module_param(irq_debug, int, 0644); -module_param(debug_latency, int, 0644); -module_param(disable_ir, int, 0444); - -module_param(fdsr, int, 0444); -module_param(gbuffers, int, 0444); -module_param(gbufsize, int, 0444); -module_param(reset_crop, int, 0444); - -module_param(v4l2, int, 0644); -module_param(bigendian, int, 0644); -module_param(irq_iswitch, int, 0644); -module_param(combfilter, int, 0444); -module_param(lumafilter, int, 0444); -module_param(automute, int, 0444); -module_param(chroma_agc, int, 0444); -module_param(adc_crush, int, 0444); -module_param(whitecrush_upper, int, 0444); -module_param(whitecrush_lower, int, 0444); -module_param(vcr_hack, int, 0444); -module_param(uv_ratio, int, 0444); -module_param(full_luma_range, int, 0444); -module_param(coring, int, 0444); - -module_param_array(radio, int, NULL, 0444); -module_param_array(video_nr, int, NULL, 0444); -module_param_array(radio_nr, int, NULL, 0444); -module_param_array(vbi_nr, int, NULL, 0444); - -MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)"); -MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian"); -MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)"); -MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)"); -MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)"); -MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)"); -MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); -MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8"); -MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000"); -MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default " - "is 1 (yes) for compatibility with older applications"); -MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)"); -MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)"); -MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)"); -MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207"); -MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127"); -MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); -MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); -MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50"); -MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)"); -MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)"); -MODULE_PARM_DESC(video_nr, "video device numbers"); -MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); -MODULE_PARM_DESC(radio_nr, "radio device numbers"); - -MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards"); -MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(BTTV_VERSION); - -/* ----------------------------------------------------------------------- */ -/* sysfs */ - -static ssize_t show_card(struct device *cd, - struct device_attribute *attr, char *buf) -{ - struct video_device *vfd = container_of(cd, struct video_device, dev); - struct bttv *btv = video_get_drvdata(vfd); - return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET); -} -static DEVICE_ATTR(card, S_IRUGO, show_card, NULL); - -/* ----------------------------------------------------------------------- */ -/* dvb auto-load setup */ -#if defined(CONFIG_MODULES) && defined(MODULE) -static void request_module_async(struct work_struct *work) -{ - request_module("dvb-bt8xx"); -} - -static void request_modules(struct bttv *dev) -{ - INIT_WORK(&dev->request_module_wk, request_module_async); - schedule_work(&dev->request_module_wk); -} - -static void flush_request_modules(struct bttv *dev) -{ - flush_work_sync(&dev->request_module_wk); -} -#else -#define request_modules(dev) -#define flush_request_modules(dev) -#endif /* CONFIG_MODULES */ - - -/* ----------------------------------------------------------------------- */ -/* static data */ - -/* special timing tables from conexant... */ -static u8 SRAM_Table[][60] = -{ - /* PAL digital input over GPIO[7:0] */ - { - 45, // 45 bytes following - 0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16, - 0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00, - 0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00, - 0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37, - 0x37,0x00,0xAF,0x21,0x00 - }, - /* NTSC digital input over GPIO[7:0] */ - { - 51, // 51 bytes following - 0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06, - 0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00, - 0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07, - 0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6, - 0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21, - 0x00, - }, - // TGB_NTSC392 // quartzsight - // This table has been modified to be used for Fusion Rev D - { - 0x2A, // size of table = 42 - 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24, - 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10, - 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00, - 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3, - 0x20, 0x00 - } -}; - -/* minhdelayx1 first video pixel we can capture on a line and - hdelayx1 start of active video, both relative to rising edge of - /HRESET pulse (0H) in 1 / fCLKx1. - swidth width of active video and - totalwidth total line width, both in 1 / fCLKx1. - sqwidth total line width in square pixels. - vdelay start of active video in 2 * field lines relative to - trailing edge of /VRESET pulse (VDELAY register). - sheight height of active video in 2 * field lines. - videostart0 ITU-R frame line number of the line corresponding - to vdelay in the first field. */ -#define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth, \ - vdelay, sheight, videostart0) \ - .cropcap.bounds.left = minhdelayx1, \ - /* * 2 because vertically we count field lines times two, */ \ - /* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */ \ - .cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \ - /* 4 is a safety margin at the end of the line. */ \ - .cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4, \ - .cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY, \ - .cropcap.defrect.left = hdelayx1, \ - .cropcap.defrect.top = (videostart0) * 2, \ - .cropcap.defrect.width = swidth, \ - .cropcap.defrect.height = sheight, \ - .cropcap.pixelaspect.numerator = totalwidth, \ - .cropcap.pixelaspect.denominator = sqwidth, - -const struct bttv_tvnorm bttv_tvnorms[] = { - /* PAL-BDGHI */ - /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ - /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ - { - .v4l2_id = V4L2_STD_PAL, - .name = "PAL", - .Fsc = 35468950, - .swidth = 924, - .sheight = 576, - .totalwidth = 1135, - .adelay = 0x7f, - .bdelay = 0x72, - .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1), - .scaledtwidth = 1135, - .hdelayx1 = 186, - .hactivex1 = 924, - .vdelay = 0x20, - .vbipack = 255, /* min (2048 / 4, 0x1ff) & 0xff */ - .sram = 0, - /* ITU-R frame line number of the first VBI line - we can capture, of the first and second field. - The last line is determined by cropcap.bounds. */ - .vbistart = { 7, 320 }, - CROPCAP(/* minhdelayx1 */ 68, - /* hdelayx1 */ 186, - /* Should be (768 * 1135 + 944 / 2) / 944. - cropcap.defrect is used for image width - checks, so we keep the old value 924. */ - /* swidth */ 924, - /* totalwidth */ 1135, - /* sqwidth */ 944, - /* vdelay */ 0x20, - /* sheight */ 576, - /* videostart0 */ 23) - /* bt878 (and bt848?) can capture another - line below active video. */ - .cropcap.bounds.height = (576 + 2) + 0x20 - 2, - },{ - .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, - .name = "NTSC", - .Fsc = 28636363, - .swidth = 768, - .sheight = 480, - .totalwidth = 910, - .adelay = 0x68, - .bdelay = 0x5d, - .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0), - .scaledtwidth = 910, - .hdelayx1 = 128, - .hactivex1 = 910, - .vdelay = 0x1a, - .vbipack = 144, /* min (1600 / 4, 0x1ff) & 0xff */ - .sram = 1, - .vbistart = { 10, 273 }, - CROPCAP(/* minhdelayx1 */ 68, - /* hdelayx1 */ 128, - /* Should be (640 * 910 + 780 / 2) / 780? */ - /* swidth */ 768, - /* totalwidth */ 910, - /* sqwidth */ 780, - /* vdelay */ 0x1a, - /* sheight */ 480, - /* videostart0 */ 23) - },{ - .v4l2_id = V4L2_STD_SECAM, - .name = "SECAM", - .Fsc = 35468950, - .swidth = 924, - .sheight = 576, - .totalwidth = 1135, - .adelay = 0x7f, - .bdelay = 0xb0, - .iform = (BT848_IFORM_SECAM|BT848_IFORM_XT1), - .scaledtwidth = 1135, - .hdelayx1 = 186, - .hactivex1 = 922, - .vdelay = 0x20, - .vbipack = 255, - .sram = 0, /* like PAL, correct? */ - .vbistart = { 7, 320 }, - CROPCAP(/* minhdelayx1 */ 68, - /* hdelayx1 */ 186, - /* swidth */ 924, - /* totalwidth */ 1135, - /* sqwidth */ 944, - /* vdelay */ 0x20, - /* sheight */ 576, - /* videostart0 */ 23) - },{ - .v4l2_id = V4L2_STD_PAL_Nc, - .name = "PAL-Nc", - .Fsc = 28636363, - .swidth = 640, - .sheight = 576, - .totalwidth = 910, - .adelay = 0x68, - .bdelay = 0x5d, - .iform = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0), - .scaledtwidth = 780, - .hdelayx1 = 130, - .hactivex1 = 734, - .vdelay = 0x1a, - .vbipack = 144, - .sram = -1, - .vbistart = { 7, 320 }, - CROPCAP(/* minhdelayx1 */ 68, - /* hdelayx1 */ 130, - /* swidth */ (640 * 910 + 780 / 2) / 780, - /* totalwidth */ 910, - /* sqwidth */ 780, - /* vdelay */ 0x1a, - /* sheight */ 576, - /* videostart0 */ 23) - },{ - .v4l2_id = V4L2_STD_PAL_M, - .name = "PAL-M", - .Fsc = 28636363, - .swidth = 640, - .sheight = 480, - .totalwidth = 910, - .adelay = 0x68, - .bdelay = 0x5d, - .iform = (BT848_IFORM_PAL_M|BT848_IFORM_XT0), - .scaledtwidth = 780, - .hdelayx1 = 135, - .hactivex1 = 754, - .vdelay = 0x1a, - .vbipack = 144, - .sram = -1, - .vbistart = { 10, 273 }, - CROPCAP(/* minhdelayx1 */ 68, - /* hdelayx1 */ 135, - /* swidth */ (640 * 910 + 780 / 2) / 780, - /* totalwidth */ 910, - /* sqwidth */ 780, - /* vdelay */ 0x1a, - /* sheight */ 480, - /* videostart0 */ 23) - },{ - .v4l2_id = V4L2_STD_PAL_N, - .name = "PAL-N", - .Fsc = 35468950, - .swidth = 768, - .sheight = 576, - .totalwidth = 1135, - .adelay = 0x7f, - .bdelay = 0x72, - .iform = (BT848_IFORM_PAL_N|BT848_IFORM_XT1), - .scaledtwidth = 944, - .hdelayx1 = 186, - .hactivex1 = 922, - .vdelay = 0x20, - .vbipack = 144, - .sram = -1, - .vbistart = { 7, 320 }, - CROPCAP(/* minhdelayx1 */ 68, - /* hdelayx1 */ 186, - /* swidth */ (768 * 1135 + 944 / 2) / 944, - /* totalwidth */ 1135, - /* sqwidth */ 944, - /* vdelay */ 0x20, - /* sheight */ 576, - /* videostart0 */ 23) - },{ - .v4l2_id = V4L2_STD_NTSC_M_JP, - .name = "NTSC-JP", - .Fsc = 28636363, - .swidth = 640, - .sheight = 480, - .totalwidth = 910, - .adelay = 0x68, - .bdelay = 0x5d, - .iform = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0), - .scaledtwidth = 780, - .hdelayx1 = 135, - .hactivex1 = 754, - .vdelay = 0x16, - .vbipack = 144, - .sram = -1, - .vbistart = { 10, 273 }, - CROPCAP(/* minhdelayx1 */ 68, - /* hdelayx1 */ 135, - /* swidth */ (640 * 910 + 780 / 2) / 780, - /* totalwidth */ 910, - /* sqwidth */ 780, - /* vdelay */ 0x16, - /* sheight */ 480, - /* videostart0 */ 23) - },{ - /* that one hopefully works with the strange timing - * which video recorders produce when playing a NTSC - * tape on a PAL TV ... */ - .v4l2_id = V4L2_STD_PAL_60, - .name = "PAL-60", - .Fsc = 35468950, - .swidth = 924, - .sheight = 480, - .totalwidth = 1135, - .adelay = 0x7f, - .bdelay = 0x72, - .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1), - .scaledtwidth = 1135, - .hdelayx1 = 186, - .hactivex1 = 924, - .vdelay = 0x1a, - .vbipack = 255, - .vtotal = 524, - .sram = -1, - .vbistart = { 10, 273 }, - CROPCAP(/* minhdelayx1 */ 68, - /* hdelayx1 */ 186, - /* swidth */ 924, - /* totalwidth */ 1135, - /* sqwidth */ 944, - /* vdelay */ 0x1a, - /* sheight */ 480, - /* videostart0 */ 23) - } -}; -static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); - -/* ----------------------------------------------------------------------- */ -/* bttv format list - packed pixel formats must come first */ -static const struct bttv_format formats[] = { - { - .name = "8 bpp, gray", - .fourcc = V4L2_PIX_FMT_GREY, - .btformat = BT848_COLOR_FMT_Y8, - .depth = 8, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "8 bpp, dithered color", - .fourcc = V4L2_PIX_FMT_HI240, - .btformat = BT848_COLOR_FMT_RGB8, - .depth = 8, - .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER, - },{ - .name = "15 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_RGB555, - .btformat = BT848_COLOR_FMT_RGB15, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "15 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB555X, - .btformat = BT848_COLOR_FMT_RGB15, - .btswap = 0x03, /* byteswap */ - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "16 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_RGB565, - .btformat = BT848_COLOR_FMT_RGB16, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "16 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB565X, - .btformat = BT848_COLOR_FMT_RGB16, - .btswap = 0x03, /* byteswap */ - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "24 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_BGR24, - .btformat = BT848_COLOR_FMT_RGB24, - .depth = 24, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "32 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_BGR32, - .btformat = BT848_COLOR_FMT_RGB32, - .depth = 32, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "32 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB32, - .btformat = BT848_COLOR_FMT_RGB32, - .btswap = 0x0f, /* byte+word swap */ - .depth = 32, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "4:2:2, packed, YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .btformat = BT848_COLOR_FMT_YUY2, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .btformat = BT848_COLOR_FMT_YUY2, - .btswap = 0x03, /* byteswap */ - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - },{ - .name = "4:2:2, planar, Y-Cb-Cr", - .fourcc = V4L2_PIX_FMT_YUV422P, - .btformat = BT848_COLOR_FMT_YCrCb422, - .depth = 16, - .flags = FORMAT_FLAGS_PLANAR, - .hshift = 1, - .vshift = 0, - },{ - .name = "4:2:0, planar, Y-Cb-Cr", - .fourcc = V4L2_PIX_FMT_YUV420, - .btformat = BT848_COLOR_FMT_YCrCb422, - .depth = 12, - .flags = FORMAT_FLAGS_PLANAR, - .hshift = 1, - .vshift = 1, - },{ - .name = "4:2:0, planar, Y-Cr-Cb", - .fourcc = V4L2_PIX_FMT_YVU420, - .btformat = BT848_COLOR_FMT_YCrCb422, - .depth = 12, - .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb, - .hshift = 1, - .vshift = 1, - },{ - .name = "4:1:1, planar, Y-Cb-Cr", - .fourcc = V4L2_PIX_FMT_YUV411P, - .btformat = BT848_COLOR_FMT_YCrCb411, - .depth = 12, - .flags = FORMAT_FLAGS_PLANAR, - .hshift = 2, - .vshift = 0, - },{ - .name = "4:1:0, planar, Y-Cb-Cr", - .fourcc = V4L2_PIX_FMT_YUV410, - .btformat = BT848_COLOR_FMT_YCrCb411, - .depth = 9, - .flags = FORMAT_FLAGS_PLANAR, - .hshift = 2, - .vshift = 2, - },{ - .name = "4:1:0, planar, Y-Cr-Cb", - .fourcc = V4L2_PIX_FMT_YVU410, - .btformat = BT848_COLOR_FMT_YCrCb411, - .depth = 9, - .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb, - .hshift = 2, - .vshift = 2, - },{ - .name = "raw scanlines", - .fourcc = -1, - .btformat = BT848_COLOR_FMT_RAW, - .depth = 8, - .flags = FORMAT_FLAGS_RAW, - } -}; -static const unsigned int FORMATS = ARRAY_SIZE(formats); - -/* ----------------------------------------------------------------------- */ - -#define V4L2_CID_PRIVATE_CHROMA_AGC (V4L2_CID_PRIVATE_BASE + 0) -#define V4L2_CID_PRIVATE_COMBFILTER (V4L2_CID_PRIVATE_BASE + 1) -#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 2) -#define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_PRIVATE_BASE + 3) -#define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_PRIVATE_BASE + 4) -#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5) -#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6) -#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7) -#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8) -#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9) -#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10) -#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11) - -static const struct v4l2_queryctrl no_ctl = { - .name = "42", - .flags = V4L2_CTRL_FLAG_DISABLED, -}; -static const struct v4l2_queryctrl bttv_ctls[] = { - /* --- video --- */ - { - .id = V4L2_CID_BRIGHTNESS, - .name = "Brightness", - .minimum = 0, - .maximum = 65535, - .step = 256, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_CONTRAST, - .name = "Contrast", - .minimum = 0, - .maximum = 65535, - .step = 128, - .default_value = 27648, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_SATURATION, - .name = "Saturation", - .minimum = 0, - .maximum = 65535, - .step = 128, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_HUE, - .name = "Hue", - .minimum = 0, - .maximum = 65535, - .step = 256, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - /* --- audio --- */ - { - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 65535, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_BALANCE, - .name = "Balance", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_BASS, - .name = "Bass", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_TREBLE, - .name = "Treble", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - /* --- private --- */ - { - .id = V4L2_CID_PRIVATE_CHROMA_AGC, - .name = "chroma agc", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_COMBFILTER, - .name = "combfilter", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_AUTOMUTE, - .name = "automute", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_LUMAFILTER, - .name = "luma decimation filter", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_AGC_CRUSH, - .name = "agc crush", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_VCR_HACK, - .name = "vcr hack", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER, - .name = "whitecrush upper", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 0xCF, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER, - .name = "whitecrush lower", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 0x7F, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_PRIVATE_UV_RATIO, - .name = "uv ratio", - .minimum = 0, - .maximum = 100, - .step = 1, - .default_value = 50, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, - .name = "full luma range", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_CORING, - .name = "coring", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - } - - - -}; - -static const struct v4l2_queryctrl *ctrl_by_id(int id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(bttv_ctls); i++) - if (bttv_ctls[i].id == id) - return bttv_ctls+i; - - return NULL; -} - -/* ----------------------------------------------------------------------- */ -/* resource management */ - -/* - RESOURCE_ allocated by freed by - - VIDEO_READ bttv_read 1) bttv_read 2) - - VIDEO_STREAM VIDIOC_STREAMON VIDIOC_STREAMOFF - VIDIOC_QBUF 1) bttv_release - VIDIOCMCAPTURE 1) - - OVERLAY VIDIOCCAPTURE on VIDIOCCAPTURE off - VIDIOC_OVERLAY on VIDIOC_OVERLAY off - 3) bttv_release - - VBI VIDIOC_STREAMON VIDIOC_STREAMOFF - VIDIOC_QBUF 1) bttv_release - bttv_read, bttv_poll 1) 4) - - 1) The resource must be allocated when we enter buffer prepare functions - and remain allocated while buffers are in the DMA queue. - 2) This is a single frame read. - 3) VIDIOC_S_FBUF and VIDIOC_S_FMT (OVERLAY) still work when - RESOURCE_OVERLAY is allocated. - 4) This is a continuous read, implies VIDIOC_STREAMON. - - Note this driver permits video input and standard changes regardless if - resources are allocated. -*/ - -#define VBI_RESOURCES (RESOURCE_VBI) -#define VIDEO_RESOURCES (RESOURCE_VIDEO_READ | \ - RESOURCE_VIDEO_STREAM | \ - RESOURCE_OVERLAY) - -static -int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit) -{ - int xbits; /* mutual exclusive resources */ - - if (fh->resources & bit) - /* have it already allocated */ - return 1; - - xbits = bit; - if (bit & (RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM)) - xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM; - - /* is it free? */ - if (btv->resources & xbits) { - /* no, someone else uses it */ - goto fail; - } - - if ((bit & VIDEO_RESOURCES) - && 0 == (btv->resources & VIDEO_RESOURCES)) { - /* Do crop - use current, don't - use default parameters. */ - __s32 top = btv->crop[!!fh->do_crop].rect.top; - - if (btv->vbi_end > top) - goto fail; - - /* We cannot capture the same line as video and VBI data. - Claim scan lines crop[].rect.top to bottom. */ - btv->crop_start = top; - } else if (bit & VBI_RESOURCES) { - __s32 end = fh->vbi_fmt.end; - - if (end > btv->crop_start) - goto fail; - - /* Claim scan lines above fh->vbi_fmt.end. */ - btv->vbi_end = end; - } - - /* it's free, grab it */ - fh->resources |= bit; - btv->resources |= bit; - return 1; - - fail: - return 0; -} - -static -int check_btres(struct bttv_fh *fh, int bit) -{ - return (fh->resources & bit); -} - -static -int locked_btres(struct bttv *btv, int bit) -{ - return (btv->resources & bit); -} - -/* Call with btv->lock down. */ -static void -disclaim_vbi_lines(struct bttv *btv) -{ - btv->vbi_end = 0; -} - -/* Call with btv->lock down. */ -static void -disclaim_video_lines(struct bttv *btv) -{ - const struct bttv_tvnorm *tvnorm; - u8 crop; - - tvnorm = &bttv_tvnorms[btv->tvnorm]; - btv->crop_start = tvnorm->cropcap.bounds.top - + tvnorm->cropcap.bounds.height; - - /* VBI capturing ends at VDELAY, start of video capturing, no - matter how many lines the VBI RISC program expects. When video - capturing is off, it shall no longer "preempt" VBI capturing, - so we set VDELAY to maximum. */ - crop = btread(BT848_E_CROP) | 0xc0; - btwrite(crop, BT848_E_CROP); - btwrite(0xfe, BT848_E_VDELAY_LO); - btwrite(crop, BT848_O_CROP); - btwrite(0xfe, BT848_O_VDELAY_LO); -} - -static -void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits) -{ - if ((fh->resources & bits) != bits) { - /* trying to free resources not allocated by us ... */ - pr_err("BUG! (btres)\n"); - } - fh->resources &= ~bits; - btv->resources &= ~bits; - - bits = btv->resources; - - if (0 == (bits & VIDEO_RESOURCES)) - disclaim_video_lines(btv); - - if (0 == (bits & VBI_RESOURCES)) - disclaim_vbi_lines(btv); -} - -/* ----------------------------------------------------------------------- */ -/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC */ - -/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C - PLL_X = Reference pre-divider (0=1, 1=2) - PLL_C = Post divider (0=6, 1=4) - PLL_I = Integer input - PLL_F = Fractional input - - F_input = 28.636363 MHz: - PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0 -*/ - -static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout) -{ - unsigned char fl, fh, fi; - - /* prevent overflows */ - fin/=4; - fout/=4; - - fout*=12; - fi=fout/fin; - - fout=(fout%fin)*256; - fh=fout/fin; - - fout=(fout%fin)*256; - fl=fout/fin; - - btwrite(fl, BT848_PLL_F_LO); - btwrite(fh, BT848_PLL_F_HI); - btwrite(fi|BT848_PLL_X, BT848_PLL_XCI); -} - -static void set_pll(struct bttv *btv) -{ - int i; - - if (!btv->pll.pll_crystal) - return; - - if (btv->pll.pll_ofreq == btv->pll.pll_current) { - dprintk("%d: PLL: no change required\n", btv->c.nr); - return; - } - - if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) { - /* no PLL needed */ - if (btv->pll.pll_current == 0) - return; - if (bttv_verbose) - pr_info("%d: PLL can sleep, using XTAL (%d)\n", - btv->c.nr, btv->pll.pll_ifreq); - btwrite(0x00,BT848_TGCTRL); - btwrite(0x00,BT848_PLL_XCI); - btv->pll.pll_current = 0; - return; - } - - if (bttv_verbose) - pr_info("%d: Setting PLL: %d => %d (needs up to 100ms)\n", - btv->c.nr, - btv->pll.pll_ifreq, btv->pll.pll_ofreq); - set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq); - - for (i=0; i<10; i++) { - /* Let other people run while the PLL stabilizes */ - msleep(10); - - if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) { - btwrite(0,BT848_DSTATUS); - } else { - btwrite(0x08,BT848_TGCTRL); - btv->pll.pll_current = btv->pll.pll_ofreq; - if (bttv_verbose) - pr_info("PLL set ok\n"); - return; - } - } - btv->pll.pll_current = -1; - if (bttv_verbose) - pr_info("Setting PLL failed\n"); - return; -} - -/* used to switch between the bt848's analog/digital video capture modes */ -static void bt848A_set_timing(struct bttv *btv) -{ - int i, len; - int table_idx = bttv_tvnorms[btv->tvnorm].sram; - int fsc = bttv_tvnorms[btv->tvnorm].Fsc; - - if (btv->input == btv->dig) { - dprintk("%d: load digital timing table (table_idx=%d)\n", - btv->c.nr,table_idx); - - /* timing change...reset timing generator address */ - btwrite(0x00, BT848_TGCTRL); - btwrite(0x02, BT848_TGCTRL); - btwrite(0x00, BT848_TGCTRL); - - len=SRAM_Table[table_idx][0]; - for(i = 1; i <= len; i++) - btwrite(SRAM_Table[table_idx][i],BT848_TGLB); - btv->pll.pll_ofreq = 27000000; - - set_pll(btv); - btwrite(0x11, BT848_TGCTRL); - btwrite(0x41, BT848_DVSIF); - } else { - btv->pll.pll_ofreq = fsc; - set_pll(btv); - btwrite(0x0, BT848_DVSIF); - } -} - -/* ----------------------------------------------------------------------- */ - -static void bt848_bright(struct bttv *btv, int bright) -{ - int value; - - // printk("set bright: %d\n", bright); // DEBUG - btv->bright = bright; - - /* We want -128 to 127 we get 0-65535 */ - value = (bright >> 8) - 128; - btwrite(value & 0xff, BT848_BRIGHT); -} - -static void bt848_hue(struct bttv *btv, int hue) -{ - int value; - - btv->hue = hue; - - /* -128 to 127 */ - value = (hue >> 8) - 128; - btwrite(value & 0xff, BT848_HUE); -} - -static void bt848_contrast(struct bttv *btv, int cont) -{ - int value,hibit; - - btv->contrast = cont; - - /* 0-511 */ - value = (cont >> 7); - hibit = (value >> 6) & 4; - btwrite(value & 0xff, BT848_CONTRAST_LO); - btaor(hibit, ~4, BT848_E_CONTROL); - btaor(hibit, ~4, BT848_O_CONTROL); -} - -static void bt848_sat(struct bttv *btv, int color) -{ - int val_u,val_v,hibits; - - btv->saturation = color; - - /* 0-511 for the color */ - val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; - val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; - hibits = (val_u >> 7) & 2; - hibits |= (val_v >> 8) & 1; - btwrite(val_u & 0xff, BT848_SAT_U_LO); - btwrite(val_v & 0xff, BT848_SAT_V_LO); - btaor(hibits, ~3, BT848_E_CONTROL); - btaor(hibits, ~3, BT848_O_CONTROL); -} - -/* ----------------------------------------------------------------------- */ - -static int -video_mux(struct bttv *btv, unsigned int input) -{ - int mux,mask2; - - if (input >= bttv_tvcards[btv->c.type].video_inputs) - return -EINVAL; - - /* needed by RemoteVideo MX */ - mask2 = bttv_tvcards[btv->c.type].gpiomask2; - if (mask2) - gpio_inout(mask2,mask2); - - if (input == btv->svhs) { - btor(BT848_CONTROL_COMP, BT848_E_CONTROL); - btor(BT848_CONTROL_COMP, BT848_O_CONTROL); - } else { - btand(~BT848_CONTROL_COMP, BT848_E_CONTROL); - btand(~BT848_CONTROL_COMP, BT848_O_CONTROL); - } - mux = bttv_muxsel(btv, input); - btaor(mux<<5, ~(3<<5), BT848_IFORM); - dprintk("%d: video mux: input=%d mux=%d\n", btv->c.nr, input, mux); - - /* card specific hook */ - if(bttv_tvcards[btv->c.type].muxsel_hook) - bttv_tvcards[btv->c.type].muxsel_hook (btv, input); - return 0; -} - -static char *audio_modes[] = { - "audio: tuner", "audio: radio", "audio: extern", - "audio: intern", "audio: mute" -}; - -static int -audio_mux(struct bttv *btv, int input, int mute) -{ - int gpio_val, signal; - struct v4l2_control ctrl; - - gpio_inout(bttv_tvcards[btv->c.type].gpiomask, - bttv_tvcards[btv->c.type].gpiomask); - signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; - - btv->mute = mute; - btv->audio = input; - - /* automute */ - mute = mute || (btv->opt_automute && !signal && !btv->radio_user); - - if (mute) - gpio_val = bttv_tvcards[btv->c.type].gpiomute; - else - gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; - - switch (btv->c.type) { - case BTTV_BOARD_VOODOOTV_FM: - case BTTV_BOARD_VOODOOTV_200: - gpio_val = bttv_tda9880_setnorm(btv, gpio_val); - break; - - default: - gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); - } - - if (bttv_gpio) - bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]); - if (in_interrupt()) - return 0; - - ctrl.id = V4L2_CID_AUDIO_MUTE; - ctrl.value = btv->mute; - bttv_call_all(btv, core, s_ctrl, &ctrl); - if (btv->sd_msp34xx) { - u32 in; - - /* Note: the inputs tuner/radio/extern/intern are translated - to msp routings. This assumes common behavior for all msp3400 - based TV cards. When this assumption fails, then the - specific MSP routing must be added to the card table. - For now this is sufficient. */ - switch (input) { - case TVAUDIO_INPUT_RADIO: - /* Some boards need the msp do to the radio demod */ - if (btv->radio_uses_msp_demodulator) { - in = MSP_INPUT_DEFAULT; - break; - } - in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - case TVAUDIO_INPUT_EXTERN: - in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - case TVAUDIO_INPUT_INTERN: - /* Yes, this is the same input as for RADIO. I doubt - if this is ever used. The only board with an INTERN - input is the BTTV_BOARD_AVERMEDIA98. I wonder how - that was tested. My guess is that the whole INTERN - input does not work. */ - in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - case TVAUDIO_INPUT_TUNER: - default: - /* This is the only card that uses TUNER2, and afaik, - is the only difference between the VOODOOTV_FM - and VOODOOTV_200 */ - if (btv->c.type == BTTV_BOARD_VOODOOTV_200) - in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \ - MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER); - else - in = MSP_INPUT_DEFAULT; - break; - } - v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, - in, MSP_OUTPUT_DEFAULT, 0); - } - if (btv->sd_tvaudio) { - v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, - input, 0, 0); - } - return 0; -} - -static inline int -audio_mute(struct bttv *btv, int mute) -{ - return audio_mux(btv, btv->audio, mute); -} - -static inline int -audio_input(struct bttv *btv, int input) -{ - return audio_mux(btv, input, btv->mute); -} - -static void -bttv_crop_calc_limits(struct bttv_crop *c) -{ - /* Scale factor min. 1:1, max. 16:1. Min. image size - 48 x 32. Scaled width must be a multiple of 4. */ - - if (1) { - /* For bug compatibility with VIDIOCGCAP and image - size checks in earlier driver versions. */ - c->min_scaled_width = 48; - c->min_scaled_height = 32; - } else { - c->min_scaled_width = - (max(48, c->rect.width >> 4) + 3) & ~3; - c->min_scaled_height = - max(32, c->rect.height >> 4); - } - - c->max_scaled_width = c->rect.width & ~3; - c->max_scaled_height = c->rect.height; -} - -static void -bttv_crop_reset(struct bttv_crop *c, unsigned int norm) -{ - c->rect = bttv_tvnorms[norm].cropcap.defrect; - bttv_crop_calc_limits(c); -} - -/* Call with btv->lock down. */ -static int -set_tvnorm(struct bttv *btv, unsigned int norm) -{ - const struct bttv_tvnorm *tvnorm; - v4l2_std_id id; - - BUG_ON(norm >= BTTV_TVNORMS); - BUG_ON(btv->tvnorm >= BTTV_TVNORMS); - - tvnorm = &bttv_tvnorms[norm]; - - if (memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap, - sizeof (tvnorm->cropcap))) { - bttv_crop_reset(&btv->crop[0], norm); - btv->crop[1] = btv->crop[0]; /* current = default */ - - if (0 == (btv->resources & VIDEO_RESOURCES)) { - btv->crop_start = tvnorm->cropcap.bounds.top - + tvnorm->cropcap.bounds.height; - } - } - - btv->tvnorm = norm; - - btwrite(tvnorm->adelay, BT848_ADELAY); - btwrite(tvnorm->bdelay, BT848_BDELAY); - btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), - BT848_IFORM); - btwrite(tvnorm->vbipack, BT848_VBI_PACK_SIZE); - btwrite(1, BT848_VBI_PACK_DEL); - bt848A_set_timing(btv); - - switch (btv->c.type) { - case BTTV_BOARD_VOODOOTV_FM: - case BTTV_BOARD_VOODOOTV_200: - bttv_tda9880_setnorm(btv, gpio_read()); - break; - } - id = tvnorm->v4l2_id; - bttv_call_all(btv, core, s_std, id); - - return 0; -} - -/* Call with btv->lock down. */ -static void -set_input(struct bttv *btv, unsigned int input, unsigned int norm) -{ - unsigned long flags; - - btv->input = input; - if (irq_iswitch) { - spin_lock_irqsave(&btv->s_lock,flags); - if (btv->curr.frame_irq) { - /* active capture -> delayed input switch */ - btv->new_input = input; - } else { - video_mux(btv,input); - } - spin_unlock_irqrestore(&btv->s_lock,flags); - } else { - video_mux(btv,input); - } - audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ? - TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN); - set_tvnorm(btv, norm); -} - -static void init_irqreg(struct bttv *btv) -{ - /* clear status */ - btwrite(0xfffffUL, BT848_INT_STAT); - - if (bttv_tvcards[btv->c.type].no_video) { - /* i2c only */ - btwrite(BT848_INT_I2CDONE, - BT848_INT_MASK); - } else { - /* full video */ - btwrite((btv->triton1) | - (btv->gpioirq ? BT848_INT_GPINT : 0) | - BT848_INT_SCERR | - (fdsr ? BT848_INT_FDSR : 0) | - BT848_INT_RISCI | BT848_INT_OCERR | - BT848_INT_FMTCHG|BT848_INT_HLOCK| - BT848_INT_I2CDONE, - BT848_INT_MASK); - } -} - -static void init_bt848(struct bttv *btv) -{ - int val; - - if (bttv_tvcards[btv->c.type].no_video) { - /* very basic init only */ - init_irqreg(btv); - return; - } - - btwrite(0x00, BT848_CAP_CTL); - btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); - btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); - - /* set planar and packed mode trigger points and */ - /* set rising edge of inverted GPINTR pin as irq trigger */ - btwrite(BT848_GPIO_DMA_CTL_PKTP_32| - BT848_GPIO_DMA_CTL_PLTP1_16| - BT848_GPIO_DMA_CTL_PLTP23_16| - BT848_GPIO_DMA_CTL_GPINTC| - BT848_GPIO_DMA_CTL_GPINTI, - BT848_GPIO_DMA_CTL); - - val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; - btwrite(val, BT848_E_SCLOOP); - btwrite(val, BT848_O_SCLOOP); - - btwrite(0x20, BT848_E_VSCALE_HI); - btwrite(0x20, BT848_O_VSCALE_HI); - btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), - BT848_ADC); - - btwrite(whitecrush_upper, BT848_WC_UP); - btwrite(whitecrush_lower, BT848_WC_DOWN); - - if (btv->opt_lumafilter) { - btwrite(0, BT848_E_CONTROL); - btwrite(0, BT848_O_CONTROL); - } else { - btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL); - btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL); - } - - bt848_bright(btv, btv->bright); - bt848_hue(btv, btv->hue); - bt848_contrast(btv, btv->contrast); - bt848_sat(btv, btv->saturation); - - /* interrupt */ - init_irqreg(btv); -} - -static void bttv_reinit_bt848(struct bttv *btv) -{ - unsigned long flags; - - if (bttv_verbose) - pr_info("%d: reset, reinitialize\n", btv->c.nr); - spin_lock_irqsave(&btv->s_lock,flags); - btv->errors=0; - bttv_set_dma(btv,0); - spin_unlock_irqrestore(&btv->s_lock,flags); - - init_bt848(btv); - btv->pll.pll_current = -1; - set_input(btv, btv->input, btv->tvnorm); -} - -static int bttv_g_ctrl(struct file *file, void *priv, - struct v4l2_control *c) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - c->value = btv->bright; - break; - case V4L2_CID_HUE: - c->value = btv->hue; - break; - case V4L2_CID_CONTRAST: - c->value = btv->contrast; - break; - case V4L2_CID_SATURATION: - c->value = btv->saturation; - break; - - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - bttv_call_all(btv, core, g_ctrl, c); - break; - - case V4L2_CID_PRIVATE_CHROMA_AGC: - c->value = btv->opt_chroma_agc; - break; - case V4L2_CID_PRIVATE_COMBFILTER: - c->value = btv->opt_combfilter; - break; - case V4L2_CID_PRIVATE_LUMAFILTER: - c->value = btv->opt_lumafilter; - break; - case V4L2_CID_PRIVATE_AUTOMUTE: - c->value = btv->opt_automute; - break; - case V4L2_CID_PRIVATE_AGC_CRUSH: - c->value = btv->opt_adc_crush; - break; - case V4L2_CID_PRIVATE_VCR_HACK: - c->value = btv->opt_vcr_hack; - break; - case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: - c->value = btv->opt_whitecrush_upper; - break; - case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: - c->value = btv->opt_whitecrush_lower; - break; - case V4L2_CID_PRIVATE_UV_RATIO: - c->value = btv->opt_uv_ratio; - break; - case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: - c->value = btv->opt_full_luma_range; - break; - case V4L2_CID_PRIVATE_CORING: - c->value = btv->opt_coring; - break; - default: - return -EINVAL; - } - return 0; -} - -static int bttv_s_ctrl(struct file *file, void *f, - struct v4l2_control *c) -{ - int err; - int val; - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - err = v4l2_prio_check(&btv->prio, fh->prio); - if (0 != err) - return err; - - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - bt848_bright(btv, c->value); - break; - case V4L2_CID_HUE: - bt848_hue(btv, c->value); - break; - case V4L2_CID_CONTRAST: - bt848_contrast(btv, c->value); - break; - case V4L2_CID_SATURATION: - bt848_sat(btv, c->value); - break; - case V4L2_CID_AUDIO_MUTE: - audio_mute(btv, c->value); - /* fall through */ - case V4L2_CID_AUDIO_VOLUME: - if (btv->volume_gpio) - btv->volume_gpio(btv, c->value); - - bttv_call_all(btv, core, s_ctrl, c); - break; - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - bttv_call_all(btv, core, s_ctrl, c); - break; - - case V4L2_CID_PRIVATE_CHROMA_AGC: - btv->opt_chroma_agc = c->value; - val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; - btwrite(val, BT848_E_SCLOOP); - btwrite(val, BT848_O_SCLOOP); - break; - case V4L2_CID_PRIVATE_COMBFILTER: - btv->opt_combfilter = c->value; - break; - case V4L2_CID_PRIVATE_LUMAFILTER: - btv->opt_lumafilter = c->value; - if (btv->opt_lumafilter) { - btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL); - btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL); - } else { - btor(BT848_CONTROL_LDEC, BT848_E_CONTROL); - btor(BT848_CONTROL_LDEC, BT848_O_CONTROL); - } - break; - case V4L2_CID_PRIVATE_AUTOMUTE: - btv->opt_automute = c->value; - break; - case V4L2_CID_PRIVATE_AGC_CRUSH: - btv->opt_adc_crush = c->value; - btwrite(BT848_ADC_RESERVED | - (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), - BT848_ADC); - break; - case V4L2_CID_PRIVATE_VCR_HACK: - btv->opt_vcr_hack = c->value; - break; - case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: - btv->opt_whitecrush_upper = c->value; - btwrite(c->value, BT848_WC_UP); - break; - case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: - btv->opt_whitecrush_lower = c->value; - btwrite(c->value, BT848_WC_DOWN); - break; - case V4L2_CID_PRIVATE_UV_RATIO: - btv->opt_uv_ratio = c->value; - bt848_sat(btv, btv->saturation); - break; - case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: - btv->opt_full_luma_range = c->value; - btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM); - break; - case V4L2_CID_PRIVATE_CORING: - btv->opt_coring = c->value; - btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM); - break; - default: - return -EINVAL; - } - return 0; -} - -/* ----------------------------------------------------------------------- */ - -void bttv_gpio_tracking(struct bttv *btv, char *comment) -{ - unsigned int outbits, data; - outbits = btread(BT848_GPIO_OUT_EN); - data = btread(BT848_GPIO_DATA); - pr_debug("%d: gpio: en=%08x, out=%08x in=%08x [%s]\n", - btv->c.nr, outbits, data & outbits, data & ~outbits, comment); -} - -static void bttv_field_count(struct bttv *btv) -{ - int need_count = 0; - - if (btv->users) - need_count++; - - if (need_count) { - /* start field counter */ - btor(BT848_INT_VSYNC,BT848_INT_MASK); - } else { - /* stop field counter */ - btand(~BT848_INT_VSYNC,BT848_INT_MASK); - btv->field_count = 0; - } -} - -static const struct bttv_format* -format_by_fourcc(int fourcc) -{ - unsigned int i; - - for (i = 0; i < FORMATS; i++) { - if (-1 == formats[i].fourcc) - continue; - if (formats[i].fourcc == fourcc) - return formats+i; - } - return NULL; -} - -/* ----------------------------------------------------------------------- */ -/* misc helpers */ - -static int -bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, - struct bttv_buffer *new) -{ - struct bttv_buffer *old; - unsigned long flags; - int retval = 0; - - dprintk("switch_overlay: enter [new=%p]\n", new); - if (new) - new->vb.state = VIDEOBUF_DONE; - spin_lock_irqsave(&btv->s_lock,flags); - old = btv->screen; - btv->screen = new; - btv->loop_irq |= 1; - bttv_set_dma(btv, 0x03); - spin_unlock_irqrestore(&btv->s_lock,flags); - if (NULL != old) { - dprintk("switch_overlay: old=%p state is %d\n", - old, old->vb.state); - bttv_dma_free(&fh->cap,btv, old); - kfree(old); - } - if (NULL == new) - free_btres_lock(btv,fh,RESOURCE_OVERLAY); - dprintk("switch_overlay: done\n"); - return retval; -} - -/* ----------------------------------------------------------------------- */ -/* video4linux (1) interface */ - -static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, - struct bttv_buffer *buf, - const struct bttv_format *fmt, - unsigned int width, unsigned int height, - enum v4l2_field field) -{ - struct bttv_fh *fh = q->priv_data; - int redo_dma_risc = 0; - struct bttv_crop c; - int norm; - int rc; - - /* check settings */ - if (NULL == fmt) - return -EINVAL; - if (fmt->btformat == BT848_COLOR_FMT_RAW) { - width = RAW_BPL; - height = RAW_LINES*2; - if (width*height > buf->vb.bsize) - return -EINVAL; - buf->vb.size = buf->vb.bsize; - - /* Make sure tvnorm and vbi_end remain consistent - until we're done. */ - - norm = btv->tvnorm; - - /* In this mode capturing always starts at defrect.top - (default VDELAY), ignoring cropping parameters. */ - if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) { - return -EINVAL; - } - - c.rect = bttv_tvnorms[norm].cropcap.defrect; - } else { - norm = btv->tvnorm; - c = btv->crop[!!fh->do_crop]; - - if (width < c.min_scaled_width || - width > c.max_scaled_width || - height < c.min_scaled_height) - return -EINVAL; - - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_ALTERNATE: - /* btv->crop counts frame lines. Max. scale - factor is 16:1 for frames, 8:1 for fields. */ - if (height * 2 > c.max_scaled_height) - return -EINVAL; - break; - - default: - if (height > c.max_scaled_height) - return -EINVAL; - break; - } - - buf->vb.size = (width * height * fmt->depth) >> 3; - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) - return -EINVAL; - } - - /* alloc + fill struct bttv_buffer (if changed) */ - if (buf->vb.width != width || buf->vb.height != height || - buf->vb.field != field || - buf->tvnorm != norm || buf->fmt != fmt || - buf->crop.top != c.rect.top || - buf->crop.left != c.rect.left || - buf->crop.width != c.rect.width || - buf->crop.height != c.rect.height) { - buf->vb.width = width; - buf->vb.height = height; - buf->vb.field = field; - buf->tvnorm = norm; - buf->fmt = fmt; - buf->crop = c.rect; - redo_dma_risc = 1; - } - - /* alloc risc memory */ - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - redo_dma_risc = 1; - if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf))) - goto fail; - } - - if (redo_dma_risc) - if (0 != (rc = bttv_buffer_risc(btv,buf))) - goto fail; - - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - - fail: - bttv_dma_free(q,btv,buf); - return rc; -} - -static int -buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) -{ - struct bttv_fh *fh = q->priv_data; - - *size = fh->fmt->depth*fh->width*fh->height >> 3; - if (0 == *count) - *count = gbuffers; - if (*size * *count > gbuffers * gbufsize) - *count = (gbuffers * gbufsize) / *size; - return 0; -} - -static int -buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); - struct bttv_fh *fh = q->priv_data; - - return bttv_prepare_buffer(q,fh->btv, buf, fh->fmt, - fh->width, fh->height, field); -} - -static void -buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); - struct bttv_fh *fh = q->priv_data; - struct bttv *btv = fh->btv; - - buf->vb.state = VIDEOBUF_QUEUED; - list_add_tail(&buf->vb.queue,&btv->capture); - if (!btv->curr.frame_irq) { - btv->loop_irq |= 1; - bttv_set_dma(btv, 0x03); - } -} - -static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); - struct bttv_fh *fh = q->priv_data; - - bttv_dma_free(q,fh->btv,buf); -} - -static struct videobuf_queue_ops bttv_video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, -}; - -static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - unsigned int i; - int err; - - err = v4l2_prio_check(&btv->prio, fh->prio); - if (err) - goto err; - - for (i = 0; i < BTTV_TVNORMS; i++) - if (*id & bttv_tvnorms[i].v4l2_id) - break; - if (i == BTTV_TVNORMS) { - err = -EINVAL; - goto err; - } - - set_tvnorm(btv, i); - -err: - - return err; -} - -static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML) - *id = V4L2_STD_625_50; - else - *id = V4L2_STD_525_60; - return 0; -} - -static int bttv_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - int rc = 0; - - if (i->index >= bttv_tvcards[btv->c.type].video_inputs) { - rc = -EINVAL; - goto err; - } - - i->type = V4L2_INPUT_TYPE_CAMERA; - i->audioset = 1; - - if (btv->tuner_type != TUNER_ABSENT && i->index == 0) { - sprintf(i->name, "Television"); - i->type = V4L2_INPUT_TYPE_TUNER; - i->tuner = 0; - } else if (i->index == btv->svhs) { - sprintf(i->name, "S-Video"); - } else { - sprintf(i->name, "Composite%d", i->index); - } - - if (i->index == btv->input) { - __u32 dstatus = btread(BT848_DSTATUS); - if (0 == (dstatus & BT848_DSTATUS_PRES)) - i->status |= V4L2_IN_ST_NO_SIGNAL; - if (0 == (dstatus & BT848_DSTATUS_HLOC)) - i->status |= V4L2_IN_ST_NO_H_LOCK; - } - - i->std = BTTV_NORMS; - -err: - - return rc; -} - -static int bttv_g_input(struct file *file, void *priv, unsigned int *i) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - *i = btv->input; - - return 0; -} - -static int bttv_s_input(struct file *file, void *priv, unsigned int i) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - int err; - - err = v4l2_prio_check(&btv->prio, fh->prio); - if (unlikely(err)) - goto err; - - if (i > bttv_tvcards[btv->c.type].video_inputs) { - err = -EINVAL; - goto err; - } - - set_input(btv, i, btv->tvnorm); - -err: - return 0; -} - -static int bttv_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - int err; - - if (unlikely(0 != t->index)) - return -EINVAL; - - if (unlikely(btv->tuner_type == TUNER_ABSENT)) { - err = -EINVAL; - goto err; - } - - err = v4l2_prio_check(&btv->prio, fh->prio); - if (unlikely(err)) - goto err; - - bttv_call_all(btv, tuner, s_tuner, t); - - if (btv->audio_mode_gpio) - btv->audio_mode_gpio(btv, t, 1); - -err: - - return 0; -} - -static int bttv_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - f->frequency = btv->freq; - - return 0; -} - -static int bttv_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - int err; - - if (unlikely(f->tuner != 0)) - return -EINVAL; - - err = v4l2_prio_check(&btv->prio, fh->prio); - if (unlikely(err)) - goto err; - - if (unlikely(f->type != (btv->radio_user - ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV))) { - err = -EINVAL; - goto err; - } - btv->freq = f->frequency; - bttv_call_all(btv, tuner, s_frequency, f); - if (btv->has_matchbox && btv->radio_user) - tea5757_set_freq(btv, btv->freq); -err: - - return 0; -} - -static int bttv_log_status(struct file *file, void *f) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - bttv_call_all(btv, core, log_status); - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int bttv_g_register(struct file *file, void *f, - struct v4l2_dbg_register *reg) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; - - /* bt848 has a 12-bit register space */ - reg->reg &= 0xfff; - reg->val = btread(reg->reg); - reg->size = 1; - - return 0; -} - -static int bttv_s_register(struct file *file, void *f, - struct v4l2_dbg_register *reg) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; - - /* bt848 has a 12-bit register space */ - reg->reg &= 0xfff; - btwrite(reg->val, reg->reg); - - return 0; -} -#endif - -/* Given cropping boundaries b and the scaled width and height of a - single field or frame, which must not exceed hardware limits, this - function adjusts the cropping parameters c. */ -static void -bttv_crop_adjust (struct bttv_crop * c, - const struct v4l2_rect * b, - __s32 width, - __s32 height, - enum v4l2_field field) -{ - __s32 frame_height = height << !V4L2_FIELD_HAS_BOTH(field); - __s32 max_left; - __s32 max_top; - - if (width < c->min_scaled_width) { - /* Max. hor. scale factor 16:1. */ - c->rect.width = width * 16; - } else if (width > c->max_scaled_width) { - /* Min. hor. scale factor 1:1. */ - c->rect.width = width; - - max_left = b->left + b->width - width; - max_left = min(max_left, (__s32) MAX_HDELAY); - if (c->rect.left > max_left) - c->rect.left = max_left; - } - - if (height < c->min_scaled_height) { - /* Max. vert. scale factor 16:1, single fields 8:1. */ - c->rect.height = height * 16; - } else if (frame_height > c->max_scaled_height) { - /* Min. vert. scale factor 1:1. - Top and height count field lines times two. */ - c->rect.height = (frame_height + 1) & ~1; - - max_top = b->top + b->height - c->rect.height; - if (c->rect.top > max_top) - c->rect.top = max_top; - } - - bttv_crop_calc_limits(c); -} - -/* Returns an error if scaling to a frame or single field with the given - width and height is not possible with the current cropping parameters - and width aligned according to width_mask. If adjust_size is TRUE the - function may adjust the width and/or height instead, rounding width - to (width + width_bias) & width_mask. If adjust_crop is TRUE it may - also adjust the current cropping parameters to get closer to the - desired image size. */ -static int -limit_scaled_size_lock (struct bttv_fh * fh, - __s32 * width, - __s32 * height, - enum v4l2_field field, - unsigned int width_mask, - unsigned int width_bias, - int adjust_size, - int adjust_crop) -{ - struct bttv *btv = fh->btv; - const struct v4l2_rect *b; - struct bttv_crop *c; - __s32 min_width; - __s32 min_height; - __s32 max_width; - __s32 max_height; - int rc; - - BUG_ON((int) width_mask >= 0 || - width_bias >= (unsigned int) -width_mask); - - /* Make sure tvnorm, vbi_end and the current cropping parameters - remain consistent until we're done. */ - - b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; - - /* Do crop - use current, don't - use default parameters. */ - c = &btv->crop[!!fh->do_crop]; - - if (fh->do_crop - && adjust_size - && adjust_crop - && !locked_btres(btv, VIDEO_RESOURCES)) { - min_width = 48; - min_height = 32; - - /* We cannot scale up. When the scaled image is larger - than crop.rect we adjust the crop.rect as required - by the V4L2 spec, hence cropcap.bounds are our limit. */ - max_width = min(b->width, (__s32) MAX_HACTIVE); - max_height = b->height; - - /* We cannot capture the same line as video and VBI data. - Note btv->vbi_end is really a minimum, see - bttv_vbi_try_fmt(). */ - if (btv->vbi_end > b->top) { - max_height -= btv->vbi_end - b->top; - rc = -EBUSY; - if (min_height > max_height) - goto fail; - } - } else { - rc = -EBUSY; - if (btv->vbi_end > c->rect.top) - goto fail; - - min_width = c->min_scaled_width; - min_height = c->min_scaled_height; - max_width = c->max_scaled_width; - max_height = c->max_scaled_height; - - adjust_crop = 0; - } - - min_width = (min_width - width_mask - 1) & width_mask; - max_width = max_width & width_mask; - - /* Max. scale factor is 16:1 for frames, 8:1 for fields. */ - min_height = min_height; - /* Min. scale factor is 1:1. */ - max_height >>= !V4L2_FIELD_HAS_BOTH(field); - - if (adjust_size) { - *width = clamp(*width, min_width, max_width); - *height = clamp(*height, min_height, max_height); - - /* Round after clamping to avoid overflow. */ - *width = (*width + width_bias) & width_mask; - - if (adjust_crop) { - bttv_crop_adjust(c, b, *width, *height, field); - - if (btv->vbi_end > c->rect.top) { - /* Move the crop window out of the way. */ - c->rect.top = btv->vbi_end; - } - } - } else { - rc = -EINVAL; - if (*width < min_width || - *height < min_height || - *width > max_width || - *height > max_height || - 0 != (*width & ~width_mask)) - goto fail; - } - - rc = 0; /* success */ - - fail: - - return rc; -} - -/* Returns an error if the given overlay window dimensions are not - possible with the current cropping parameters. If adjust_size is - TRUE the function may adjust the window width and/or height - instead, however it always rounds the horizontal position and - width as btcx_align() does. If adjust_crop is TRUE the function - may also adjust the current cropping parameters to get closer - to the desired window size. */ -static int -verify_window_lock (struct bttv_fh * fh, - struct v4l2_window * win, - int adjust_size, - int adjust_crop) -{ - enum v4l2_field field; - unsigned int width_mask; - int rc; - - if (win->w.width < 48 || win->w.height < 32) - return -EINVAL; - if (win->clipcount > 2048) - return -EINVAL; - - field = win->field; - - if (V4L2_FIELD_ANY == field) { - __s32 height2; - - height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; - field = (win->w.height > height2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_TOP; - } - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_INTERLACED: - break; - default: - return -EINVAL; - } - - /* 4-byte alignment. */ - if (NULL == fh->ovfmt) - return -EINVAL; - width_mask = ~0; - switch (fh->ovfmt->depth) { - case 8: - case 24: - width_mask = ~3; - break; - case 16: - width_mask = ~1; - break; - case 32: - break; - default: - BUG(); - } - - win->w.width -= win->w.left & ~width_mask; - win->w.left = (win->w.left - width_mask - 1) & width_mask; - - rc = limit_scaled_size_lock(fh, &win->w.width, &win->w.height, - field, width_mask, - /* width_bias: round down */ 0, - adjust_size, adjust_crop); - if (0 != rc) - return rc; - - win->field = field; - return 0; -} - -static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, - struct v4l2_window *win, int fixup) -{ - struct v4l2_clip *clips = NULL; - int n,size,retval = 0; - - if (NULL == fh->ovfmt) - return -EINVAL; - if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) - return -EINVAL; - retval = verify_window_lock(fh, win, - /* adjust_size */ fixup, - /* adjust_crop */ fixup); - if (0 != retval) - return retval; - - /* copy clips -- luckily v4l1 + v4l2 are binary - compatible here ...*/ - n = win->clipcount; - size = sizeof(*clips)*(n+4); - clips = kmalloc(size,GFP_KERNEL); - if (NULL == clips) - return -ENOMEM; - if (n > 0) { - if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) { - kfree(clips); - return -EFAULT; - } - } - - /* clip against screen */ - if (NULL != btv->fbuf.base) - n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, - &win->w, clips, n); - btcx_sort_clips(clips,n); - - /* 4-byte alignments */ - switch (fh->ovfmt->depth) { - case 8: - case 24: - btcx_align(&win->w, clips, n, 3); - break; - case 16: - btcx_align(&win->w, clips, n, 1); - break; - case 32: - /* no alignment fixups needed */ - break; - default: - BUG(); - } - - kfree(fh->ov.clips); - fh->ov.clips = clips; - fh->ov.nclips = n; - - fh->ov.w = win->w; - fh->ov.field = win->field; - fh->ov.setup_ok = 1; - - btv->init.ov.w.width = win->w.width; - btv->init.ov.w.height = win->w.height; - btv->init.ov.field = win->field; - - /* update overlay if needed */ - retval = 0; - if (check_btres(fh, RESOURCE_OVERLAY)) { - struct bttv_buffer *new; - - new = videobuf_sg_alloc(sizeof(*new)); - new->crop = btv->crop[!!fh->do_crop].rect; - bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); - retval = bttv_switch_overlay(btv,fh,new); - } - return retval; -} - -/* ----------------------------------------------------------------------- */ - -static struct videobuf_queue* bttv_queue(struct bttv_fh *fh) -{ - struct videobuf_queue* q = NULL; - - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - q = &fh->cap; - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - q = &fh->vbi; - break; - default: - BUG(); - } - return q; -} - -static int bttv_resource(struct bttv_fh *fh) -{ - int res = 0; - - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - res = RESOURCE_VIDEO_STREAM; - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - res = RESOURCE_VBI; - break; - default: - BUG(); - } - return res; -} - -static int bttv_switch_type(struct bttv_fh *fh, enum v4l2_buf_type type) -{ - struct videobuf_queue *q = bttv_queue(fh); - int res = bttv_resource(fh); - - if (check_btres(fh,res)) - return -EBUSY; - if (videobuf_queue_is_busy(q)) - return -EBUSY; - fh->type = type; - return 0; -} - -static void -pix_format_set_size (struct v4l2_pix_format * f, - const struct bttv_format * fmt, - unsigned int width, - unsigned int height) -{ - f->width = width; - f->height = height; - - if (fmt->flags & FORMAT_FLAGS_PLANAR) { - f->bytesperline = width; /* Y plane */ - f->sizeimage = (width * height * fmt->depth) >> 3; - } else { - f->bytesperline = (width * fmt->depth) >> 3; - f->sizeimage = height * f->bytesperline; - } -} - -static int bttv_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct bttv_fh *fh = priv; - - pix_format_set_size(&f->fmt.pix, fh->fmt, - fh->width, fh->height); - f->fmt.pix.field = fh->cap.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - - return 0; -} - -static int bttv_g_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct bttv_fh *fh = priv; - - f->fmt.win.w = fh->ov.w; - f->fmt.win.field = fh->ov.field; - - return 0; -} - -static int bttv_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - const struct bttv_format *fmt; - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - enum v4l2_field field; - __s32 width, height; - int rc; - - fmt = format_by_fourcc(f->fmt.pix.pixelformat); - if (NULL == fmt) - return -EINVAL; - - field = f->fmt.pix.field; - - if (V4L2_FIELD_ANY == field) { - __s32 height2; - - height2 = btv->crop[!!fh->do_crop].rect.height >> 1; - field = (f->fmt.pix.height > height2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - } - - if (V4L2_FIELD_SEQ_BT == field) - field = V4L2_FIELD_SEQ_TB; - - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_ALTERNATE: - case V4L2_FIELD_INTERLACED: - break; - case V4L2_FIELD_SEQ_TB: - if (fmt->flags & FORMAT_FLAGS_PLANAR) - return -EINVAL; - break; - default: - return -EINVAL; - } - - width = f->fmt.pix.width; - height = f->fmt.pix.height; - - rc = limit_scaled_size_lock(fh, &width, &height, field, - /* width_mask: 4 pixels */ ~3, - /* width_bias: nearest */ 2, - /* adjust_size */ 1, - /* adjust_crop */ 0); - if (0 != rc) - return rc; - - /* update data for the application */ - f->fmt.pix.field = field; - pix_format_set_size(&f->fmt.pix, fmt, width, height); - - return 0; -} - -static int bttv_try_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct bttv_fh *fh = priv; - - return verify_window_lock(fh, &f->fmt.win, - /* adjust_size */ 1, - /* adjust_crop */ 0); -} - -static int bttv_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - int retval; - const struct bttv_format *fmt; - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - __s32 width, height; - enum v4l2_field field; - - retval = bttv_switch_type(fh, f->type); - if (0 != retval) - return retval; - - retval = bttv_try_fmt_vid_cap(file, priv, f); - if (0 != retval) - return retval; - - width = f->fmt.pix.width; - height = f->fmt.pix.height; - field = f->fmt.pix.field; - - retval = limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field, - /* width_mask: 4 pixels */ ~3, - /* width_bias: nearest */ 2, - /* adjust_size */ 1, - /* adjust_crop */ 1); - if (0 != retval) - return retval; - - f->fmt.pix.field = field; - - fmt = format_by_fourcc(f->fmt.pix.pixelformat); - - /* update our state informations */ - fh->fmt = fmt; - fh->cap.field = f->fmt.pix.field; - fh->cap.last = V4L2_FIELD_NONE; - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - btv->init.fmt = fmt; - btv->init.width = f->fmt.pix.width; - btv->init.height = f->fmt.pix.height; - - return 0; -} - -static int bttv_s_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - if (no_overlay > 0) { - pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - - return setup_window_lock(fh, btv, &f->fmt.win, 1); -} - -static int bttv_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - if (0 == v4l2) - return -EINVAL; - - strlcpy(cap->driver, "bttv", sizeof(cap->driver)); - strlcpy(cap->card, btv->video_dev->name, sizeof(cap->card)); - snprintf(cap->bus_info, sizeof(cap->bus_info), - "PCI:%s", pci_name(btv->c.pci)); - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VBI_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - if (no_overlay <= 0) - cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; - - /* - * No need to lock here: those vars are initialized during board - * probe and remains untouched during the rest of the driver lifecycle - */ - if (btv->has_saa6588) - cap->capabilities |= V4L2_CAP_RDS_CAPTURE; - if (btv->tuner_type != TUNER_ABSENT) - cap->capabilities |= V4L2_CAP_TUNER; - return 0; -} - -static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f) -{ - int index = -1, i; - - for (i = 0; i < FORMATS; i++) { - if (formats[i].fourcc != -1) - index++; - if ((unsigned int)index == f->index) - break; - } - if (FORMATS == i) - return -EINVAL; - - f->pixelformat = formats[i].fourcc; - strlcpy(f->description, formats[i].name, sizeof(f->description)); - - return i; -} - -static int bttv_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - int rc = bttv_enum_fmt_cap_ovr(f); - - if (rc < 0) - return rc; - - return 0; -} - -static int bttv_enum_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - int rc; - - if (no_overlay > 0) { - pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - - rc = bttv_enum_fmt_cap_ovr(f); - - if (rc < 0) - return rc; - - if (!(formats[rc].flags & FORMAT_FLAGS_PACKED)) - return -EINVAL; - - return 0; -} - -static int bttv_g_fbuf(struct file *file, void *f, - struct v4l2_framebuffer *fb) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - *fb = btv->fbuf; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - if (fh->ovfmt) - fb->fmt.pixelformat = fh->ovfmt->fourcc; - return 0; -} - -static int bttv_overlay(struct file *file, void *f, unsigned int on) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - struct bttv_buffer *new; - int retval = 0; - - if (on) { - /* verify args */ - if (unlikely(!btv->fbuf.base)) { - return -EINVAL; - } - if (unlikely(!fh->ov.setup_ok)) { - dprintk("%d: overlay: !setup_ok\n", btv->c.nr); - retval = -EINVAL; - } - if (retval) - return retval; - } - - if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) - return -EBUSY; - - if (on) { - fh->ov.tvnorm = btv->tvnorm; - new = videobuf_sg_alloc(sizeof(*new)); - new->crop = btv->crop[!!fh->do_crop].rect; - bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); - } else { - new = NULL; - } - - /* switch over */ - retval = bttv_switch_overlay(btv, fh, new); - return retval; -} - -static int bttv_s_fbuf(struct file *file, void *f, - struct v4l2_framebuffer *fb) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - const struct bttv_format *fmt; - int retval; - - if (!capable(CAP_SYS_ADMIN) && - !capable(CAP_SYS_RAWIO)) - return -EPERM; - - /* check args */ - fmt = format_by_fourcc(fb->fmt.pixelformat); - if (NULL == fmt) - return -EINVAL; - if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) - return -EINVAL; - - retval = -EINVAL; - if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { - __s32 width = fb->fmt.width; - __s32 height = fb->fmt.height; - - retval = limit_scaled_size_lock(fh, &width, &height, - V4L2_FIELD_INTERLACED, - /* width_mask */ ~3, - /* width_bias */ 2, - /* adjust_size */ 0, - /* adjust_crop */ 0); - if (0 != retval) - return retval; - } - - /* ok, accept it */ - btv->fbuf.base = fb->base; - btv->fbuf.fmt.width = fb->fmt.width; - btv->fbuf.fmt.height = fb->fmt.height; - if (0 != fb->fmt.bytesperline) - btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline; - else - btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8; - - retval = 0; - fh->ovfmt = fmt; - btv->init.ovfmt = fmt; - if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { - fh->ov.w.left = 0; - fh->ov.w.top = 0; - fh->ov.w.width = fb->fmt.width; - fh->ov.w.height = fb->fmt.height; - btv->init.ov.w.width = fb->fmt.width; - btv->init.ov.w.height = fb->fmt.height; - kfree(fh->ov.clips); - fh->ov.clips = NULL; - fh->ov.nclips = 0; - - if (check_btres(fh, RESOURCE_OVERLAY)) { - struct bttv_buffer *new; - - new = videobuf_sg_alloc(sizeof(*new)); - new->crop = btv->crop[!!fh->do_crop].rect; - bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); - retval = bttv_switch_overlay(btv, fh, new); - } - } - return retval; -} - -static int bttv_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p) -{ - struct bttv_fh *fh = priv; - return videobuf_reqbufs(bttv_queue(fh), p); -} - -static int bttv_querybuf(struct file *file, void *priv, - struct v4l2_buffer *b) -{ - struct bttv_fh *fh = priv; - return videobuf_querybuf(bttv_queue(fh), b); -} - -static int bttv_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - int res = bttv_resource(fh); - - if (!check_alloc_btres_lock(btv, fh, res)) - return -EBUSY; - - return videobuf_qbuf(bttv_queue(fh), b); -} - -static int bttv_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct bttv_fh *fh = priv; - return videobuf_dqbuf(bttv_queue(fh), b, - file->f_flags & O_NONBLOCK); -} - -static int bttv_streamon(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - int res = bttv_resource(fh); - - if (!check_alloc_btres_lock(btv, fh, res)) - return -EBUSY; - return videobuf_streamon(bttv_queue(fh)); -} - - -static int bttv_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - int retval; - int res = bttv_resource(fh); - - - retval = videobuf_streamoff(bttv_queue(fh)); - if (retval < 0) - return retval; - free_btres_lock(btv, fh, res); - return 0; -} - -static int bttv_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - const struct v4l2_queryctrl *ctrl; - - if ((c->id < V4L2_CID_BASE || - c->id >= V4L2_CID_LASTP1) && - (c->id < V4L2_CID_PRIVATE_BASE || - c->id >= V4L2_CID_PRIVATE_LASTP1)) - return -EINVAL; - - if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) - *c = no_ctl; - else { - ctrl = ctrl_by_id(c->id); - - *c = (NULL != ctrl) ? *ctrl : no_ctl; - } - - return 0; -} - -static int bttv_g_parm(struct file *file, void *f, - struct v4l2_streamparm *parm) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, - &parm->parm.capture.timeperframe); - - return 0; -} - -static int bttv_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - if (btv->tuner_type == TUNER_ABSENT) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - - t->rxsubchans = V4L2_TUNER_SUB_MONO; - bttv_call_all(btv, tuner, g_tuner, t); - strcpy(t->name, "Television"); - t->capability = V4L2_TUNER_CAP_NORM; - t->type = V4L2_TUNER_ANALOG_TV; - if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) - t->signal = 0xffff; - - if (btv->audio_mode_gpio) - btv->audio_mode_gpio(btv, t, 0); - - return 0; -} - -static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - *p = v4l2_prio_max(&btv->prio); - - return 0; -} - -static int bttv_s_priority(struct file *file, void *f, - enum v4l2_priority prio) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - int rc; - - rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); - - return rc; -} - -static int bttv_cropcap(struct file *file, void *priv, - struct v4l2_cropcap *cap) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) - return -EINVAL; - - *cap = bttv_tvnorms[btv->tvnorm].cropcap; - - return 0; -} - -static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) - return -EINVAL; - - /* No fh->do_crop = 1; because btv->crop[1] may be - inconsistent with fh->width or fh->height and apps - do not expect a change here. */ - - crop->c = btv->crop[!!fh->do_crop].rect; - - return 0; -} - -static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - const struct v4l2_rect *b; - int retval; - struct bttv_crop c; - __s32 b_left; - __s32 b_top; - __s32 b_right; - __s32 b_bottom; - - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) - return -EINVAL; - - /* Make sure tvnorm, vbi_end and the current cropping - parameters remain consistent until we're done. Note - read() may change vbi_end in check_alloc_btres_lock(). */ - retval = v4l2_prio_check(&btv->prio, fh->prio); - if (0 != retval) { - return retval; - } - - retval = -EBUSY; - - if (locked_btres(fh->btv, VIDEO_RESOURCES)) { - return retval; - } - - b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; - - b_left = b->left; - b_right = b_left + b->width; - b_bottom = b->top + b->height; - - b_top = max(b->top, btv->vbi_end); - if (b_top + 32 >= b_bottom) { - return retval; - } - - /* Min. scaled size 48 x 32. */ - c.rect.left = clamp(crop->c.left, b_left, b_right - 48); - c.rect.left = min(c.rect.left, (__s32) MAX_HDELAY); - - c.rect.width = clamp(crop->c.width, - 48, b_right - c.rect.left); - - c.rect.top = clamp(crop->c.top, b_top, b_bottom - 32); - /* Top and height must be a multiple of two. */ - c.rect.top = (c.rect.top + 1) & ~1; - - c.rect.height = clamp(crop->c.height, - 32, b_bottom - c.rect.top); - c.rect.height = (c.rect.height + 1) & ~1; - - bttv_crop_calc_limits(&c); - - btv->crop[1] = c; - - fh->do_crop = 1; - - if (fh->width < c.min_scaled_width) { - fh->width = c.min_scaled_width; - btv->init.width = c.min_scaled_width; - } else if (fh->width > c.max_scaled_width) { - fh->width = c.max_scaled_width; - btv->init.width = c.max_scaled_width; - } - - if (fh->height < c.min_scaled_height) { - fh->height = c.min_scaled_height; - btv->init.height = c.min_scaled_height; - } else if (fh->height > c.max_scaled_height) { - fh->height = c.max_scaled_height; - btv->init.height = c.max_scaled_height; - } - - return 0; -} - -static int bttv_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; - - strcpy(a->name, "audio"); - return 0; -} - -static int bttv_s_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; - - return 0; -} - -static ssize_t bttv_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct bttv_fh *fh = file->private_data; - int retval = 0; - - if (fh->btv->errors) - bttv_reinit_bt848(fh->btv); - dprintk("%d: read count=%d type=%s\n", - fh->btv->c.nr, (int)count, v4l2_type_names[fh->type]); - - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (!check_alloc_btres_lock(fh->btv, fh, RESOURCE_VIDEO_READ)) { - /* VIDEO_READ in use by another fh, - or VIDEO_STREAM by any fh. */ - return -EBUSY; - } - retval = videobuf_read_one(&fh->cap, data, count, ppos, - file->f_flags & O_NONBLOCK); - free_btres_lock(fh->btv, fh, RESOURCE_VIDEO_READ); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI)) - return -EBUSY; - retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1, - file->f_flags & O_NONBLOCK); - break; - default: - BUG(); - } - return retval; -} - -static unsigned int bttv_poll(struct file *file, poll_table *wait) -{ - struct bttv_fh *fh = file->private_data; - struct bttv_buffer *buf; - enum v4l2_field field; - unsigned int rc = POLLERR; - - if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { - if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI)) - return POLLERR; - return videobuf_poll_stream(file, &fh->vbi, wait); - } - - if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { - /* streaming capture */ - if (list_empty(&fh->cap.stream)) - goto err; - buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); - } else { - /* read() capture */ - if (NULL == fh->cap.read_buf) { - /* need to capture a new frame */ - if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) - goto err; - fh->cap.read_buf = videobuf_sg_alloc(fh->cap.msize); - if (NULL == fh->cap.read_buf) - goto err; - fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; - field = videobuf_next_field(&fh->cap); - if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) { - kfree (fh->cap.read_buf); - fh->cap.read_buf = NULL; - goto err; - } - fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); - fh->cap.read_off = 0; - } - buf = (struct bttv_buffer*)fh->cap.read_buf; - } - - poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == VIDEOBUF_DONE || - buf->vb.state == VIDEOBUF_ERROR) - rc = POLLIN|POLLRDNORM; - else - rc = 0; -err: - return rc; -} - -static int bttv_open(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct bttv *btv = video_drvdata(file); - struct bttv_fh *fh; - enum v4l2_buf_type type = 0; - - dprintk("open dev=%s\n", video_device_node_name(vdev)); - - if (vdev->vfl_type == VFL_TYPE_GRABBER) { - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } else if (vdev->vfl_type == VFL_TYPE_VBI) { - type = V4L2_BUF_TYPE_VBI_CAPTURE; - } else { - WARN_ON(1); - return -ENODEV; - } - - dprintk("%d: open called (type=%s)\n", - btv->c.nr, v4l2_type_names[type]); - - /* allocate per filehandle data */ - fh = kmalloc(sizeof(*fh), GFP_KERNEL); - if (unlikely(!fh)) - return -ENOMEM; - file->private_data = fh; - - *fh = btv->init; - - fh->type = type; - fh->ov.setup_ok = 0; - - v4l2_prio_open(&btv->prio, &fh->prio); - - videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, - &btv->c.pci->dev, &btv->s_lock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct bttv_buffer), - fh, &btv->lock); - videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, - &btv->c.pci->dev, &btv->s_lock, - V4L2_BUF_TYPE_VBI_CAPTURE, - V4L2_FIELD_SEQ_TB, - sizeof(struct bttv_buffer), - fh, &btv->lock); - set_tvnorm(btv,btv->tvnorm); - set_input(btv, btv->input, btv->tvnorm); - - btv->users++; - - /* The V4L2 spec requires one global set of cropping parameters - which only change on request. These are stored in btv->crop[1]. - However for compatibility with V4L apps and cropping unaware - V4L2 apps we now reset the cropping parameters as seen through - this fh, which is to say VIDIOC_G_CROP and scaling limit checks - will use btv->crop[0], the default cropping parameters for the - current video standard, and VIDIOC_S_FMT will not implicitely - change the cropping parameters until VIDIOC_S_CROP has been - called. */ - fh->do_crop = !reset_crop; /* module parameter */ - - /* Likewise there should be one global set of VBI capture - parameters, but for compatibility with V4L apps and earlier - driver versions each fh has its own parameters. */ - bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); - - bttv_field_count(btv); - return 0; -} - -static int bttv_release(struct file *file) -{ - struct bttv_fh *fh = file->private_data; - struct bttv *btv = fh->btv; - - /* turn off overlay */ - if (check_btres(fh, RESOURCE_OVERLAY)) - bttv_switch_overlay(btv,fh,NULL); - - /* stop video capture */ - if (check_btres(fh, RESOURCE_VIDEO_STREAM)) { - videobuf_streamoff(&fh->cap); - free_btres_lock(btv,fh,RESOURCE_VIDEO_STREAM); - } - if (fh->cap.read_buf) { - buffer_release(&fh->cap,fh->cap.read_buf); - kfree(fh->cap.read_buf); - } - if (check_btres(fh, RESOURCE_VIDEO_READ)) { - free_btres_lock(btv, fh, RESOURCE_VIDEO_READ); - } - - /* stop vbi capture */ - if (check_btres(fh, RESOURCE_VBI)) { - videobuf_stop(&fh->vbi); - free_btres_lock(btv,fh,RESOURCE_VBI); - } - - /* free stuff */ - - videobuf_mmap_free(&fh->cap); - videobuf_mmap_free(&fh->vbi); - v4l2_prio_close(&btv->prio, fh->prio); - file->private_data = NULL; - kfree(fh); - - btv->users--; - bttv_field_count(btv); - - if (!btv->users) - audio_mute(btv, 1); - - return 0; -} - -static int -bttv_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct bttv_fh *fh = file->private_data; - - dprintk("%d: mmap type=%s 0x%lx+%ld\n", - fh->btv->c.nr, v4l2_type_names[fh->type], - vma->vm_start, vma->vm_end - vma->vm_start); - return videobuf_mmap_mapper(bttv_queue(fh),vma); -} - -static const struct v4l2_file_operations bttv_fops = -{ - .owner = THIS_MODULE, - .open = bttv_open, - .release = bttv_release, - .unlocked_ioctl = video_ioctl2, - .read = bttv_read, - .mmap = bttv_mmap, - .poll = bttv_poll, -}; - -static const struct v4l2_ioctl_ops bttv_ioctl_ops = { - .vidioc_querycap = bttv_querycap, - .vidioc_enum_fmt_vid_cap = bttv_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = bttv_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = bttv_s_fmt_vid_cap, - .vidioc_enum_fmt_vid_overlay = bttv_enum_fmt_vid_overlay, - .vidioc_g_fmt_vid_overlay = bttv_g_fmt_vid_overlay, - .vidioc_try_fmt_vid_overlay = bttv_try_fmt_vid_overlay, - .vidioc_s_fmt_vid_overlay = bttv_s_fmt_vid_overlay, - .vidioc_g_fmt_vbi_cap = bttv_g_fmt_vbi_cap, - .vidioc_try_fmt_vbi_cap = bttv_try_fmt_vbi_cap, - .vidioc_s_fmt_vbi_cap = bttv_s_fmt_vbi_cap, - .vidioc_g_audio = bttv_g_audio, - .vidioc_s_audio = bttv_s_audio, - .vidioc_cropcap = bttv_cropcap, - .vidioc_reqbufs = bttv_reqbufs, - .vidioc_querybuf = bttv_querybuf, - .vidioc_qbuf = bttv_qbuf, - .vidioc_dqbuf = bttv_dqbuf, - .vidioc_s_std = bttv_s_std, - .vidioc_enum_input = bttv_enum_input, - .vidioc_g_input = bttv_g_input, - .vidioc_s_input = bttv_s_input, - .vidioc_queryctrl = bttv_queryctrl, - .vidioc_g_ctrl = bttv_g_ctrl, - .vidioc_s_ctrl = bttv_s_ctrl, - .vidioc_streamon = bttv_streamon, - .vidioc_streamoff = bttv_streamoff, - .vidioc_g_tuner = bttv_g_tuner, - .vidioc_s_tuner = bttv_s_tuner, - .vidioc_g_crop = bttv_g_crop, - .vidioc_s_crop = bttv_s_crop, - .vidioc_g_fbuf = bttv_g_fbuf, - .vidioc_s_fbuf = bttv_s_fbuf, - .vidioc_overlay = bttv_overlay, - .vidioc_g_priority = bttv_g_priority, - .vidioc_s_priority = bttv_s_priority, - .vidioc_g_parm = bttv_g_parm, - .vidioc_g_frequency = bttv_g_frequency, - .vidioc_s_frequency = bttv_s_frequency, - .vidioc_log_status = bttv_log_status, - .vidioc_querystd = bttv_querystd, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = bttv_g_register, - .vidioc_s_register = bttv_s_register, -#endif -}; - -static struct video_device bttv_video_template = { - .fops = &bttv_fops, - .ioctl_ops = &bttv_ioctl_ops, - .tvnorms = BTTV_NORMS, - .current_norm = V4L2_STD_PAL, -}; - -/* ----------------------------------------------------------------------- */ -/* radio interface */ - -static int radio_open(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct bttv *btv = video_drvdata(file); - struct bttv_fh *fh; - - dprintk("open dev=%s\n", video_device_node_name(vdev)); - - dprintk("%d: open called (radio)\n", btv->c.nr); - - /* allocate per filehandle data */ - fh = kmalloc(sizeof(*fh), GFP_KERNEL); - if (unlikely(!fh)) - return -ENOMEM; - file->private_data = fh; - *fh = btv->init; - - v4l2_prio_open(&btv->prio, &fh->prio); - - btv->radio_user++; - - bttv_call_all(btv, tuner, s_radio); - audio_input(btv,TVAUDIO_INPUT_RADIO); - - return 0; -} - -static int radio_release(struct file *file) -{ - struct bttv_fh *fh = file->private_data; - struct bttv *btv = fh->btv; - struct saa6588_command cmd; - - v4l2_prio_close(&btv->prio, fh->prio); - file->private_data = NULL; - kfree(fh); - - btv->radio_user--; - - bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); - - return 0; -} - -static int radio_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - strcpy(cap->driver, "bttv"); - strlcpy(cap->card, btv->radio_dev->name, sizeof(cap->card)); - sprintf(cap->bus_info, "PCI:%s", pci_name(btv->c.pci)); - cap->capabilities = V4L2_CAP_TUNER; - - return 0; -} - -static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - if (btv->tuner_type == TUNER_ABSENT) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - strcpy(t->name, "Radio"); - t->type = V4L2_TUNER_RADIO; - - bttv_call_all(btv, tuner, g_tuner, t); - - if (btv->audio_mode_gpio) - btv->audio_mode_gpio(btv, t, 0); - - return 0; -} - -static int radio_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - if (i->index != 0) - return -EINVAL; - - strcpy(i->name, "Radio"); - i->type = V4L2_INPUT_TYPE_TUNER; - - return 0; -} - -static int radio_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; - - strcpy(a->name, "Radio"); - - return 0; -} - -static int radio_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - if (0 != t->index) - return -EINVAL; - - bttv_call_all(btv, tuner, s_tuner, t); - return 0; -} - -static int radio_s_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; - - return 0; -} - -static int radio_s_input(struct file *filp, void *priv, unsigned int i) -{ - if (unlikely(i)) - return -EINVAL; - - return 0; -} - -static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) -{ - return 0; -} - -static int radio_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - const struct v4l2_queryctrl *ctrl; - - if (c->id < V4L2_CID_BASE || - c->id >= V4L2_CID_LASTP1) - return -EINVAL; - - if (c->id == V4L2_CID_AUDIO_MUTE) { - ctrl = ctrl_by_id(c->id); - *c = *ctrl; - } else - *c = no_ctl; - - return 0; -} - -static int radio_g_input(struct file *filp, void *priv, unsigned int *i) -{ - *i = 0; - return 0; -} - -static ssize_t radio_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct bttv_fh *fh = file->private_data; - struct bttv *btv = fh->btv; - struct saa6588_command cmd; - cmd.block_count = count/3; - cmd.buffer = data; - cmd.instance = file; - cmd.result = -ENODEV; - - bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); - - return cmd.result; -} - -static unsigned int radio_poll(struct file *file, poll_table *wait) -{ - struct bttv_fh *fh = file->private_data; - struct bttv *btv = fh->btv; - struct saa6588_command cmd; - cmd.instance = file; - cmd.event_list = wait; - cmd.result = -ENODEV; - bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd); - - return cmd.result; -} - -static const struct v4l2_file_operations radio_fops = -{ - .owner = THIS_MODULE, - .open = radio_open, - .read = radio_read, - .release = radio_release, - .unlocked_ioctl = video_ioctl2, - .poll = radio_poll, -}; - -static const struct v4l2_ioctl_ops radio_ioctl_ops = { - .vidioc_querycap = radio_querycap, - .vidioc_g_tuner = radio_g_tuner, - .vidioc_enum_input = radio_enum_input, - .vidioc_g_audio = radio_g_audio, - .vidioc_s_tuner = radio_s_tuner, - .vidioc_s_audio = radio_s_audio, - .vidioc_s_input = radio_s_input, - .vidioc_s_std = radio_s_std, - .vidioc_queryctrl = radio_queryctrl, - .vidioc_g_input = radio_g_input, - .vidioc_g_ctrl = bttv_g_ctrl, - .vidioc_s_ctrl = bttv_s_ctrl, - .vidioc_g_frequency = bttv_g_frequency, - .vidioc_s_frequency = bttv_s_frequency, -}; - -static struct video_device radio_template = { - .fops = &radio_fops, - .ioctl_ops = &radio_ioctl_ops, -}; - -/* ----------------------------------------------------------------------- */ -/* some debug code */ - -static int bttv_risc_decode(u32 risc) -{ - static char *instr[16] = { - [ BT848_RISC_WRITE >> 28 ] = "write", - [ BT848_RISC_SKIP >> 28 ] = "skip", - [ BT848_RISC_WRITEC >> 28 ] = "writec", - [ BT848_RISC_JUMP >> 28 ] = "jump", - [ BT848_RISC_SYNC >> 28 ] = "sync", - [ BT848_RISC_WRITE123 >> 28 ] = "write123", - [ BT848_RISC_SKIP123 >> 28 ] = "skip123", - [ BT848_RISC_WRITE1S23 >> 28 ] = "write1s23", - }; - static int incr[16] = { - [ BT848_RISC_WRITE >> 28 ] = 2, - [ BT848_RISC_JUMP >> 28 ] = 2, - [ BT848_RISC_SYNC >> 28 ] = 2, - [ BT848_RISC_WRITE123 >> 28 ] = 5, - [ BT848_RISC_SKIP123 >> 28 ] = 2, - [ BT848_RISC_WRITE1S23 >> 28 ] = 3, - }; - static char *bits[] = { - "be0", "be1", "be2", "be3/resync", - "set0", "set1", "set2", "set3", - "clr0", "clr1", "clr2", "clr3", - "irq", "res", "eol", "sol", - }; - int i; - - pr_cont("0x%08x [ %s", risc, - instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); - for (i = ARRAY_SIZE(bits)-1; i >= 0; i--) - if (risc & (1 << (i + 12))) - pr_cont(" %s", bits[i]); - pr_cont(" count=%d ]\n", risc & 0xfff); - return incr[risc >> 28] ? incr[risc >> 28] : 1; -} - -static void bttv_risc_disasm(struct bttv *btv, - struct btcx_riscmem *risc) -{ - unsigned int i,j,n; - - pr_info("%s: risc disasm: %p [dma=0x%08lx]\n", - btv->c.v4l2_dev.name, risc->cpu, (unsigned long)risc->dma); - for (i = 0; i < (risc->size >> 2); i += n) { - pr_info("%s: 0x%lx: ", - btv->c.v4l2_dev.name, - (unsigned long)(risc->dma + (i<<2))); - n = bttv_risc_decode(le32_to_cpu(risc->cpu[i])); - for (j = 1; j < n; j++) - pr_info("%s: 0x%lx: 0x%08x [ arg #%d ]\n", - btv->c.v4l2_dev.name, - (unsigned long)(risc->dma + ((i+j)<<2)), - risc->cpu[i+j], j); - if (0 == risc->cpu[i]) - break; - } -} - -static void bttv_print_riscaddr(struct bttv *btv) -{ - pr_info(" main: %08llx\n", (unsigned long long)btv->main.dma); - pr_info(" vbi : o=%08llx e=%08llx\n", - btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, - btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0); - pr_info(" cap : o=%08llx e=%08llx\n", - btv->curr.top - ? (unsigned long long)btv->curr.top->top.dma : 0, - btv->curr.bottom - ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); - pr_info(" scr : o=%08llx e=%08llx\n", - btv->screen ? (unsigned long long)btv->screen->top.dma : 0, - btv->screen ? (unsigned long long)btv->screen->bottom.dma : 0); - bttv_risc_disasm(btv, &btv->main); -} - -/* ----------------------------------------------------------------------- */ -/* irq handler */ - -static char *irq_name[] = { - "FMTCHG", // format change detected (525 vs. 625) - "VSYNC", // vertical sync (new field) - "HSYNC", // horizontal sync - "OFLOW", // chroma/luma AGC overflow - "HLOCK", // horizontal lock changed - "VPRES", // video presence changed - "6", "7", - "I2CDONE", // hw irc operation finished - "GPINT", // gpio port triggered irq - "10", - "RISCI", // risc instruction triggered irq - "FBUS", // pixel data fifo dropped data (high pci bus latencies) - "FTRGT", // pixel data fifo overrun - "FDSR", // fifo data stream resyncronisation - "PPERR", // parity error (data transfer) - "RIPERR", // parity error (read risc instructions) - "PABORT", // pci abort - "OCERR", // risc instruction error - "SCERR", // syncronisation error -}; - -static void bttv_print_irqbits(u32 print, u32 mark) -{ - unsigned int i; - - pr_cont("bits:"); - for (i = 0; i < ARRAY_SIZE(irq_name); i++) { - if (print & (1 << i)) - pr_cont(" %s", irq_name[i]); - if (mark & (1 << i)) - pr_cont("*"); - } -} - -static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc) -{ - pr_warn("%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n", - btv->c.nr, - (unsigned long)btv->main.dma, - (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_VBI+1]), - (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_FIELD+1]), - (unsigned long)rc); - - if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) { - pr_notice("%d: Oh, there (temporarily?) is no input signal. " - "Ok, then this is harmless, don't worry ;)\n", - btv->c.nr); - return; - } - pr_notice("%d: Uhm. Looks like we have unusual high IRQ latencies\n", - btv->c.nr); - pr_notice("%d: Lets try to catch the culpit red-handed ...\n", - btv->c.nr); - dump_stack(); -} - -static int -bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) -{ - struct bttv_buffer *item; - - memset(set,0,sizeof(*set)); - - /* capture request ? */ - if (!list_empty(&btv->capture)) { - set->frame_irq = 1; - item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue); - if (V4L2_FIELD_HAS_TOP(item->vb.field)) - set->top = item; - if (V4L2_FIELD_HAS_BOTTOM(item->vb.field)) - set->bottom = item; - - /* capture request for other field ? */ - if (!V4L2_FIELD_HAS_BOTH(item->vb.field) && - (item->vb.queue.next != &btv->capture)) { - item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue); - /* Mike Isely <isely@pobox.com> - Only check - * and set up the bottom field in the logic - * below. Don't ever do the top field. This - * of course means that if we set up the - * bottom field in the above code that we'll - * actually skip a field. But that's OK. - * Having processed only a single buffer this - * time, then the next time around the first - * available buffer should be for a top field. - * That will then cause us here to set up a - * top then a bottom field in the normal way. - * The alternative to this understanding is - * that we set up the second available buffer - * as a top field, but that's out of order - * since this driver always processes the top - * field first - the effect will be the two - * buffers being returned in the wrong order, - * with the second buffer also being delayed - * by one field time (owing to the fifo nature - * of videobuf). Worse still, we'll be stuck - * doing fields out of order now every time - * until something else causes a field to be - * dropped. By effectively forcing a field to - * drop this way then we always get back into - * sync within a single frame time. (Out of - * order fields can screw up deinterlacing - * algorithms.) */ - if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) { - if (NULL == set->bottom && - V4L2_FIELD_BOTTOM == item->vb.field) { - set->bottom = item; - } - if (NULL != set->top && NULL != set->bottom) - set->top_irq = 2; - } - } - } - - /* screen overlay ? */ - if (NULL != btv->screen) { - if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) { - if (NULL == set->top && NULL == set->bottom) { - set->top = btv->screen; - set->bottom = btv->screen; - } - } else { - if (V4L2_FIELD_TOP == btv->screen->vb.field && - NULL == set->top) { - set->top = btv->screen; - } - if (V4L2_FIELD_BOTTOM == btv->screen->vb.field && - NULL == set->bottom) { - set->bottom = btv->screen; - } - } - } - - dprintk("%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n", - btv->c.nr, set->top, set->bottom, - btv->screen, set->frame_irq, set->top_irq); - return 0; -} - -static void -bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup, - struct bttv_buffer_set *curr, unsigned int state) -{ - struct timeval ts; - - do_gettimeofday(&ts); - - if (wakeup->top == wakeup->bottom) { - if (NULL != wakeup->top && curr->top != wakeup->top) { - if (irq_debug > 1) - pr_debug("%d: wakeup: both=%p\n", - btv->c.nr, wakeup->top); - wakeup->top->vb.ts = ts; - wakeup->top->vb.field_count = btv->field_count; - wakeup->top->vb.state = state; - wake_up(&wakeup->top->vb.done); - } - } else { - if (NULL != wakeup->top && curr->top != wakeup->top) { - if (irq_debug > 1) - pr_debug("%d: wakeup: top=%p\n", - btv->c.nr, wakeup->top); - wakeup->top->vb.ts = ts; - wakeup->top->vb.field_count = btv->field_count; - wakeup->top->vb.state = state; - wake_up(&wakeup->top->vb.done); - } - if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) { - if (irq_debug > 1) - pr_debug("%d: wakeup: bottom=%p\n", - btv->c.nr, wakeup->bottom); - wakeup->bottom->vb.ts = ts; - wakeup->bottom->vb.field_count = btv->field_count; - wakeup->bottom->vb.state = state; - wake_up(&wakeup->bottom->vb.done); - } - } -} - -static void -bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup, - unsigned int state) -{ - struct timeval ts; - - if (NULL == wakeup) - return; - - do_gettimeofday(&ts); - wakeup->vb.ts = ts; - wakeup->vb.field_count = btv->field_count; - wakeup->vb.state = state; - wake_up(&wakeup->vb.done); -} - -static void bttv_irq_timeout(unsigned long data) -{ - struct bttv *btv = (struct bttv *)data; - struct bttv_buffer_set old,new; - struct bttv_buffer *ovbi; - struct bttv_buffer *item; - unsigned long flags; - - if (bttv_verbose) { - pr_info("%d: timeout: drop=%d irq=%d/%d, risc=%08x, ", - btv->c.nr, btv->framedrop, btv->irq_me, btv->irq_total, - btread(BT848_RISC_COUNT)); - bttv_print_irqbits(btread(BT848_INT_STAT),0); - pr_cont("\n"); - } - - spin_lock_irqsave(&btv->s_lock,flags); - - /* deactivate stuff */ - memset(&new,0,sizeof(new)); - old = btv->curr; - ovbi = btv->cvbi; - btv->curr = new; - btv->cvbi = NULL; - btv->loop_irq = 0; - bttv_buffer_activate_video(btv, &new); - bttv_buffer_activate_vbi(btv, NULL); - bttv_set_dma(btv, 0); - - /* wake up */ - bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_ERROR); - bttv_irq_wakeup_vbi(btv, ovbi, VIDEOBUF_ERROR); - - /* cancel all outstanding capture / vbi requests */ - while (!list_empty(&btv->capture)) { - item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue); - list_del(&item->vb.queue); - item->vb.state = VIDEOBUF_ERROR; - wake_up(&item->vb.done); - } - while (!list_empty(&btv->vcapture)) { - item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue); - list_del(&item->vb.queue); - item->vb.state = VIDEOBUF_ERROR; - wake_up(&item->vb.done); - } - - btv->errors++; - spin_unlock_irqrestore(&btv->s_lock,flags); -} - -static void -bttv_irq_wakeup_top(struct bttv *btv) -{ - struct bttv_buffer *wakeup = btv->curr.top; - - if (NULL == wakeup) - return; - - spin_lock(&btv->s_lock); - btv->curr.top_irq = 0; - btv->curr.top = NULL; - bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); - - do_gettimeofday(&wakeup->vb.ts); - wakeup->vb.field_count = btv->field_count; - wakeup->vb.state = VIDEOBUF_DONE; - wake_up(&wakeup->vb.done); - spin_unlock(&btv->s_lock); -} - -static inline int is_active(struct btcx_riscmem *risc, u32 rc) -{ - if (rc < risc->dma) - return 0; - if (rc > risc->dma + risc->size) - return 0; - return 1; -} - -static void -bttv_irq_switch_video(struct bttv *btv) -{ - struct bttv_buffer_set new; - struct bttv_buffer_set old; - dma_addr_t rc; - - spin_lock(&btv->s_lock); - - /* new buffer set */ - bttv_irq_next_video(btv, &new); - rc = btread(BT848_RISC_COUNT); - if ((btv->curr.top && is_active(&btv->curr.top->top, rc)) || - (btv->curr.bottom && is_active(&btv->curr.bottom->bottom, rc))) { - btv->framedrop++; - if (debug_latency) - bttv_irq_debug_low_latency(btv, rc); - spin_unlock(&btv->s_lock); - return; - } - - /* switch over */ - old = btv->curr; - btv->curr = new; - btv->loop_irq &= ~1; - bttv_buffer_activate_video(btv, &new); - bttv_set_dma(btv, 0); - - /* switch input */ - if (UNSET != btv->new_input) { - video_mux(btv,btv->new_input); - btv->new_input = UNSET; - } - - /* wake up finished buffers */ - bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_DONE); - spin_unlock(&btv->s_lock); -} - -static void -bttv_irq_switch_vbi(struct bttv *btv) -{ - struct bttv_buffer *new = NULL; - struct bttv_buffer *old; - u32 rc; - - spin_lock(&btv->s_lock); - - if (!list_empty(&btv->vcapture)) - new = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue); - old = btv->cvbi; - - rc = btread(BT848_RISC_COUNT); - if (NULL != old && (is_active(&old->top, rc) || - is_active(&old->bottom, rc))) { - btv->framedrop++; - if (debug_latency) - bttv_irq_debug_low_latency(btv, rc); - spin_unlock(&btv->s_lock); - return; - } - - /* switch */ - btv->cvbi = new; - btv->loop_irq &= ~4; - bttv_buffer_activate_vbi(btv, new); - bttv_set_dma(btv, 0); - - bttv_irq_wakeup_vbi(btv, old, VIDEOBUF_DONE); - spin_unlock(&btv->s_lock); -} - -static irqreturn_t bttv_irq(int irq, void *dev_id) -{ - u32 stat,astat; - u32 dstat; - int count; - struct bttv *btv; - int handled = 0; - - btv=(struct bttv *)dev_id; - - count=0; - while (1) { - /* get/clear interrupt status bits */ - stat=btread(BT848_INT_STAT); - astat=stat&btread(BT848_INT_MASK); - if (!astat) - break; - handled = 1; - btwrite(stat,BT848_INT_STAT); - - /* get device status bits */ - dstat=btread(BT848_DSTATUS); - - if (irq_debug) { - pr_debug("%d: irq loop=%d fc=%d riscs=%x, riscc=%08x, ", - btv->c.nr, count, btv->field_count, - stat>>28, btread(BT848_RISC_COUNT)); - bttv_print_irqbits(stat,astat); - if (stat & BT848_INT_HLOCK) - pr_cont(" HLOC => %s", - dstat & BT848_DSTATUS_HLOC - ? "yes" : "no"); - if (stat & BT848_INT_VPRES) - pr_cont(" PRES => %s", - dstat & BT848_DSTATUS_PRES - ? "yes" : "no"); - if (stat & BT848_INT_FMTCHG) - pr_cont(" NUML => %s", - dstat & BT848_DSTATUS_NUML - ? "625" : "525"); - pr_cont("\n"); - } - - if (astat&BT848_INT_VSYNC) - btv->field_count++; - - if ((astat & BT848_INT_GPINT) && btv->remote) { - bttv_input_irq(btv); - } - - if (astat & BT848_INT_I2CDONE) { - btv->i2c_done = stat; - wake_up(&btv->i2c_queue); - } - - if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) - bttv_irq_switch_vbi(btv); - - if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) - bttv_irq_wakeup_top(btv); - - if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) - bttv_irq_switch_video(btv); - - if ((astat & BT848_INT_HLOCK) && btv->opt_automute) - audio_mute(btv, btv->mute); /* trigger automute */ - - if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) { - pr_info("%d: %s%s @ %08x,", - btv->c.nr, - (astat & BT848_INT_SCERR) ? "SCERR" : "", - (astat & BT848_INT_OCERR) ? "OCERR" : "", - btread(BT848_RISC_COUNT)); - bttv_print_irqbits(stat,astat); - pr_cont("\n"); - if (bttv_debug) - bttv_print_riscaddr(btv); - } - if (fdsr && astat & BT848_INT_FDSR) { - pr_info("%d: FDSR @ %08x\n", - btv->c.nr, btread(BT848_RISC_COUNT)); - if (bttv_debug) - bttv_print_riscaddr(btv); - } - - count++; - if (count > 4) { - - if (count > 8 || !(astat & BT848_INT_GPINT)) { - btwrite(0, BT848_INT_MASK); - - pr_err("%d: IRQ lockup, cleared int mask [", - btv->c.nr); - } else { - pr_err("%d: IRQ lockup, clearing GPINT from int mask [", - btv->c.nr); - - btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT), - BT848_INT_MASK); - }; - - bttv_print_irqbits(stat,astat); - - pr_cont("]\n"); - } - } - btv->irq_total++; - if (handled) - btv->irq_me++; - return IRQ_RETVAL(handled); -} - - -/* ----------------------------------------------------------------------- */ -/* initialitation */ - -static struct video_device *vdev_init(struct bttv *btv, - const struct video_device *template, - const char *type_name) -{ - struct video_device *vfd; - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - *vfd = *template; - vfd->v4l2_dev = &btv->c.v4l2_dev; - vfd->release = video_device_release; - vfd->debug = bttv_debug; - video_set_drvdata(vfd, btv); - snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", - btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", - type_name, bttv_tvcards[btv->c.type].name); - return vfd; -} - -static void bttv_unregister_video(struct bttv *btv) -{ - if (btv->video_dev) { - if (video_is_registered(btv->video_dev)) - video_unregister_device(btv->video_dev); - else - video_device_release(btv->video_dev); - btv->video_dev = NULL; - } - if (btv->vbi_dev) { - if (video_is_registered(btv->vbi_dev)) - video_unregister_device(btv->vbi_dev); - else - video_device_release(btv->vbi_dev); - btv->vbi_dev = NULL; - } - if (btv->radio_dev) { - if (video_is_registered(btv->radio_dev)) - video_unregister_device(btv->radio_dev); - else - video_device_release(btv->radio_dev); - btv->radio_dev = NULL; - } -} - -/* register video4linux devices */ -static int __devinit bttv_register_video(struct bttv *btv) -{ - if (no_overlay > 0) - pr_notice("Overlay support disabled\n"); - - /* video */ - btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); - - if (NULL == btv->video_dev) - goto err; - if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER, - video_nr[btv->c.nr]) < 0) - goto err; - pr_info("%d: registered device %s\n", - btv->c.nr, video_device_node_name(btv->video_dev)); - if (device_create_file(&btv->video_dev->dev, - &dev_attr_card)<0) { - pr_err("%d: device_create_file 'card' failed\n", btv->c.nr); - goto err; - } - - /* vbi */ - btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi"); - - if (NULL == btv->vbi_dev) - goto err; - if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI, - vbi_nr[btv->c.nr]) < 0) - goto err; - pr_info("%d: registered device %s\n", - btv->c.nr, video_device_node_name(btv->vbi_dev)); - - if (!btv->has_radio) - return 0; - /* radio */ - btv->radio_dev = vdev_init(btv, &radio_template, "radio"); - if (NULL == btv->radio_dev) - goto err; - if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO, - radio_nr[btv->c.nr]) < 0) - goto err; - pr_info("%d: registered device %s\n", - btv->c.nr, video_device_node_name(btv->radio_dev)); - - /* all done */ - return 0; - - err: - bttv_unregister_video(btv); - return -1; -} - - -/* on OpenFirmware machines (PowerMac at least), PCI memory cycle */ -/* response on cards with no firmware is not enabled by OF */ -static void pci_set_command(struct pci_dev *dev) -{ -#if defined(__powerpc__) - unsigned int cmd; - - pci_read_config_dword(dev, PCI_COMMAND, &cmd); - cmd = (cmd | PCI_COMMAND_MEMORY ); - pci_write_config_dword(dev, PCI_COMMAND, cmd); -#endif -} - -static int __devinit bttv_probe(struct pci_dev *dev, - const struct pci_device_id *pci_id) -{ - int result; - unsigned char lat; - struct bttv *btv; - - if (bttv_num == BTTV_MAX) - return -ENOMEM; - pr_info("Bt8xx card found (%d)\n", bttv_num); - bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL); - if (btv == NULL) { - pr_err("out of memory\n"); - return -ENOMEM; - } - btv->c.nr = bttv_num; - snprintf(btv->c.v4l2_dev.name, sizeof(btv->c.v4l2_dev.name), - "bttv%d", btv->c.nr); - - /* initialize structs / fill in defaults */ - mutex_init(&btv->lock); - spin_lock_init(&btv->s_lock); - spin_lock_init(&btv->gpio_lock); - init_waitqueue_head(&btv->i2c_queue); - INIT_LIST_HEAD(&btv->c.subs); - INIT_LIST_HEAD(&btv->capture); - INIT_LIST_HEAD(&btv->vcapture); - v4l2_prio_init(&btv->prio); - - init_timer(&btv->timeout); - btv->timeout.function = bttv_irq_timeout; - btv->timeout.data = (unsigned long)btv; - - btv->i2c_rc = -1; - btv->tuner_type = UNSET; - btv->new_input = UNSET; - btv->has_radio=radio[btv->c.nr]; - - /* pci stuff (init, get irq/mmio, ... */ - btv->c.pci = dev; - btv->id = dev->device; - if (pci_enable_device(dev)) { - pr_warn("%d: Can't enable device\n", btv->c.nr); - return -EIO; - } - if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { - pr_warn("%d: No suitable DMA available\n", btv->c.nr); - return -EIO; - } - if (!request_mem_region(pci_resource_start(dev,0), - pci_resource_len(dev,0), - btv->c.v4l2_dev.name)) { - pr_warn("%d: can't request iomem (0x%llx)\n", - btv->c.nr, - (unsigned long long)pci_resource_start(dev, 0)); - return -EBUSY; - } - pci_set_master(dev); - pci_set_command(dev); - - result = v4l2_device_register(&dev->dev, &btv->c.v4l2_dev); - if (result < 0) { - pr_warn("%d: v4l2_device_register() failed\n", btv->c.nr); - goto fail0; - } - - btv->revision = dev->revision; - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - pr_info("%d: Bt%d (rev %d) at %s, irq: %d, latency: %d, mmio: 0x%llx\n", - bttv_num, btv->id, btv->revision, pci_name(dev), - btv->c.pci->irq, lat, - (unsigned long long)pci_resource_start(dev, 0)); - schedule(); - - btv->bt848_mmio = ioremap(pci_resource_start(dev, 0), 0x1000); - if (NULL == btv->bt848_mmio) { - pr_err("%d: ioremap() failed\n", btv->c.nr); - result = -EIO; - goto fail1; - } - - /* identify card */ - bttv_idcard(btv); - - /* disable irqs, register irq handler */ - btwrite(0, BT848_INT_MASK); - result = request_irq(btv->c.pci->irq, bttv_irq, - IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv); - if (result < 0) { - pr_err("%d: can't get IRQ %d\n", - bttv_num, btv->c.pci->irq); - goto fail1; - } - - if (0 != bttv_handle_chipset(btv)) { - result = -EIO; - goto fail2; - } - - /* init options from insmod args */ - btv->opt_combfilter = combfilter; - btv->opt_lumafilter = lumafilter; - btv->opt_automute = automute; - btv->opt_chroma_agc = chroma_agc; - btv->opt_adc_crush = adc_crush; - btv->opt_vcr_hack = vcr_hack; - btv->opt_whitecrush_upper = whitecrush_upper; - btv->opt_whitecrush_lower = whitecrush_lower; - btv->opt_uv_ratio = uv_ratio; - btv->opt_full_luma_range = full_luma_range; - btv->opt_coring = coring; - - /* fill struct bttv with some useful defaults */ - btv->init.btv = btv; - btv->init.ov.w.width = 320; - btv->init.ov.w.height = 240; - btv->init.fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); - btv->init.width = 320; - btv->init.height = 240; - btv->input = 0; - - /* initialize hardware */ - if (bttv_gpio) - bttv_gpio_tracking(btv,"pre-init"); - - bttv_risc_init_main(btv); - init_bt848(btv); - - /* gpio */ - btwrite(0x00, BT848_GPIO_REG_INP); - btwrite(0x00, BT848_GPIO_OUT_EN); - if (bttv_verbose) - bttv_gpio_tracking(btv,"init"); - - /* needs to be done before i2c is registered */ - bttv_init_card1(btv); - - /* register i2c + gpio */ - init_bttv_i2c(btv); - - /* some card-specific stuff (needs working i2c) */ - bttv_init_card2(btv); - bttv_init_tuner(btv); - init_irqreg(btv); - - /* register video4linux + input */ - if (!bttv_tvcards[btv->c.type].no_video) { - bttv_register_video(btv); - bt848_bright(btv,32768); - bt848_contrast(btv, 27648); - bt848_hue(btv,32768); - bt848_sat(btv,32768); - audio_mute(btv, 1); - set_input(btv, 0, btv->tvnorm); - bttv_crop_reset(&btv->crop[0], btv->tvnorm); - btv->crop[1] = btv->crop[0]; /* current = default */ - disclaim_vbi_lines(btv); - disclaim_video_lines(btv); - } - - /* add subdevices and autoload dvb-bt8xx if needed */ - if (bttv_tvcards[btv->c.type].has_dvb) { - bttv_sub_add_device(&btv->c, "dvb"); - request_modules(btv); - } - - if (!disable_ir) { - init_bttv_i2c_ir(btv); - bttv_input_init(btv); - } - - /* everything is fine */ - bttv_num++; - return 0; - -fail2: - free_irq(btv->c.pci->irq,btv); - -fail1: - v4l2_device_unregister(&btv->c.v4l2_dev); - -fail0: - if (btv->bt848_mmio) - iounmap(btv->bt848_mmio); - release_mem_region(pci_resource_start(btv->c.pci,0), - pci_resource_len(btv->c.pci,0)); - return result; -} - -static void __devexit bttv_remove(struct pci_dev *pci_dev) -{ - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct bttv *btv = to_bttv(v4l2_dev); - - if (bttv_verbose) - pr_info("%d: unloading\n", btv->c.nr); - - if (bttv_tvcards[btv->c.type].has_dvb) - flush_request_modules(btv); - - /* shutdown everything (DMA+IRQs) */ - btand(~15, BT848_GPIO_DMA_CTL); - btwrite(0, BT848_INT_MASK); - btwrite(~0x0, BT848_INT_STAT); - btwrite(0x0, BT848_GPIO_OUT_EN); - if (bttv_gpio) - bttv_gpio_tracking(btv,"cleanup"); - - /* tell gpio modules we are leaving ... */ - btv->shutdown=1; - bttv_input_fini(btv); - bttv_sub_del_devices(&btv->c); - - /* unregister i2c_bus + input */ - fini_bttv_i2c(btv); - - /* unregister video4linux */ - bttv_unregister_video(btv); - - /* free allocated memory */ - btcx_riscmem_free(btv->c.pci,&btv->main); - - /* free ressources */ - free_irq(btv->c.pci->irq,btv); - iounmap(btv->bt848_mmio); - release_mem_region(pci_resource_start(btv->c.pci,0), - pci_resource_len(btv->c.pci,0)); - - v4l2_device_unregister(&btv->c.v4l2_dev); - bttvs[btv->c.nr] = NULL; - kfree(btv); - - return; -} - -#ifdef CONFIG_PM -static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) -{ - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct bttv *btv = to_bttv(v4l2_dev); - struct bttv_buffer_set idle; - unsigned long flags; - - dprintk("%d: suspend %d\n", btv->c.nr, state.event); - - /* stop dma + irqs */ - spin_lock_irqsave(&btv->s_lock,flags); - memset(&idle, 0, sizeof(idle)); - btv->state.video = btv->curr; - btv->state.vbi = btv->cvbi; - btv->state.loop_irq = btv->loop_irq; - btv->curr = idle; - btv->loop_irq = 0; - bttv_buffer_activate_video(btv, &idle); - bttv_buffer_activate_vbi(btv, NULL); - bttv_set_dma(btv, 0); - btwrite(0, BT848_INT_MASK); - spin_unlock_irqrestore(&btv->s_lock,flags); - - /* save bt878 state */ - btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN); - btv->state.gpio_data = gpio_read(); - - /* save pci state */ - pci_save_state(pci_dev); - if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { - pci_disable_device(pci_dev); - btv->state.disabled = 1; - } - return 0; -} - -static int bttv_resume(struct pci_dev *pci_dev) -{ - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct bttv *btv = to_bttv(v4l2_dev); - unsigned long flags; - int err; - - dprintk("%d: resume\n", btv->c.nr); - - /* restore pci state */ - if (btv->state.disabled) { - err=pci_enable_device(pci_dev); - if (err) { - pr_warn("%d: Can't enable device\n", btv->c.nr); - return err; - } - btv->state.disabled = 0; - } - err=pci_set_power_state(pci_dev, PCI_D0); - if (err) { - pci_disable_device(pci_dev); - pr_warn("%d: Can't enable device\n", btv->c.nr); - btv->state.disabled = 1; - return err; - } - - pci_restore_state(pci_dev); - - /* restore bt878 state */ - bttv_reinit_bt848(btv); - gpio_inout(0xffffff, btv->state.gpio_enable); - gpio_write(btv->state.gpio_data); - - /* restart dma */ - spin_lock_irqsave(&btv->s_lock,flags); - btv->curr = btv->state.video; - btv->cvbi = btv->state.vbi; - btv->loop_irq = btv->state.loop_irq; - bttv_buffer_activate_video(btv, &btv->curr); - bttv_buffer_activate_vbi(btv, btv->cvbi); - bttv_set_dma(btv, 0); - spin_unlock_irqrestore(&btv->s_lock,flags); - return 0; -} -#endif - -static struct pci_device_id bttv_pci_tbl[] = { - {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848), 0}, - {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0}, - {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0}, - {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0}, - {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_FUSION879), 0}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); - -static struct pci_driver bttv_pci_driver = { - .name = "bttv", - .id_table = bttv_pci_tbl, - .probe = bttv_probe, - .remove = __devexit_p(bttv_remove), -#ifdef CONFIG_PM - .suspend = bttv_suspend, - .resume = bttv_resume, -#endif -}; - -static int __init bttv_init_module(void) -{ - int ret; - - bttv_num = 0; - - pr_info("driver version %s loaded\n", BTTV_VERSION); - if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) - gbuffers = 2; - if (gbufsize > BTTV_MAX_FBUF) - gbufsize = BTTV_MAX_FBUF; - gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; - if (bttv_verbose) - pr_info("using %d buffers with %dk (%d pages) each for capture\n", - gbuffers, gbufsize >> 10, gbufsize >> PAGE_SHIFT); - - bttv_check_chipset(); - - ret = bus_register(&bttv_sub_bus_type); - if (ret < 0) { - pr_warn("bus_register error: %d\n", ret); - return ret; - } - ret = pci_register_driver(&bttv_pci_driver); - if (ret < 0) - bus_unregister(&bttv_sub_bus_type); - - return ret; -} - -static void __exit bttv_cleanup_module(void) -{ - pci_unregister_driver(&bttv_pci_driver); - bus_unregister(&bttv_sub_bus_type); -} - -module_init(bttv_init_module); -module_exit(bttv_cleanup_module); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c deleted file mode 100644 index 922e8233fd0b..000000000000 --- a/drivers/media/video/bt8xx/bttv-gpio.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - - bttv-gpio.c -- gpio sub drivers - - sysfs-based sub driver interface for bttv - mainly intended for gpio access - - - Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) - & Marcus Metzler (mocm@thp.uni-koeln.de) - (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/slab.h> -#include <asm/io.h> - -#include "bttvp.h" - -/* ----------------------------------------------------------------------- */ -/* internal: the bttv "bus" */ - -static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv) -{ - struct bttv_sub_driver *sub = to_bttv_sub_drv(drv); - int len = strlen(sub->wanted); - - if (0 == strncmp(dev_name(dev), sub->wanted, len)) - return 1; - return 0; -} - -static int bttv_sub_probe(struct device *dev) -{ - struct bttv_sub_device *sdev = to_bttv_sub_dev(dev); - struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver); - - return sub->probe ? sub->probe(sdev) : -ENODEV; -} - -static int bttv_sub_remove(struct device *dev) -{ - struct bttv_sub_device *sdev = to_bttv_sub_dev(dev); - struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver); - - if (sub->remove) - sub->remove(sdev); - return 0; -} - -struct bus_type bttv_sub_bus_type = { - .name = "bttv-sub", - .match = &bttv_sub_bus_match, - .probe = bttv_sub_probe, - .remove = bttv_sub_remove, -}; - -static void release_sub_device(struct device *dev) -{ - struct bttv_sub_device *sub = to_bttv_sub_dev(dev); - kfree(sub); -} - -int bttv_sub_add_device(struct bttv_core *core, char *name) -{ - struct bttv_sub_device *sub; - int err; - - sub = kzalloc(sizeof(*sub),GFP_KERNEL); - if (NULL == sub) - return -ENOMEM; - - sub->core = core; - sub->dev.parent = &core->pci->dev; - sub->dev.bus = &bttv_sub_bus_type; - sub->dev.release = release_sub_device; - dev_set_name(&sub->dev, "%s%d", name, core->nr); - - err = device_register(&sub->dev); - if (0 != err) { - kfree(sub); - return err; - } - pr_info("%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev)); - list_add_tail(&sub->list,&core->subs); - return 0; -} - -int bttv_sub_del_devices(struct bttv_core *core) -{ - struct bttv_sub_device *sub, *save; - - list_for_each_entry_safe(sub, save, &core->subs, list) { - list_del(&sub->list); - device_unregister(&sub->dev); - } - return 0; -} - -/* ----------------------------------------------------------------------- */ -/* external: sub-driver register/unregister */ - -int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted) -{ - sub->drv.bus = &bttv_sub_bus_type; - snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted); - return driver_register(&sub->drv); -} -EXPORT_SYMBOL(bttv_sub_register); - -int bttv_sub_unregister(struct bttv_sub_driver *sub) -{ - driver_unregister(&sub->drv); - return 0; -} -EXPORT_SYMBOL(bttv_sub_unregister); - -/* ----------------------------------------------------------------------- */ -/* external: gpio access functions */ - -void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits) -{ - struct bttv *btv = container_of(core, struct bttv, c); - unsigned long flags; - u32 data; - - spin_lock_irqsave(&btv->gpio_lock,flags); - data = btread(BT848_GPIO_OUT_EN); - data = data & ~mask; - data = data | (mask & outbits); - btwrite(data,BT848_GPIO_OUT_EN); - spin_unlock_irqrestore(&btv->gpio_lock,flags); -} - -u32 bttv_gpio_read(struct bttv_core *core) -{ - struct bttv *btv = container_of(core, struct bttv, c); - u32 value; - - value = btread(BT848_GPIO_DATA); - return value; -} - -void bttv_gpio_write(struct bttv_core *core, u32 value) -{ - struct bttv *btv = container_of(core, struct bttv, c); - - btwrite(value,BT848_GPIO_DATA); -} - -void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits) -{ - struct bttv *btv = container_of(core, struct bttv, c); - unsigned long flags; - u32 data; - - spin_lock_irqsave(&btv->gpio_lock,flags); - data = btread(BT848_GPIO_DATA); - data = data & ~mask; - data = data | (mask & bits); - btwrite(data,BT848_GPIO_DATA); - spin_unlock_irqrestore(&btv->gpio_lock,flags); -} - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c deleted file mode 100644 index 580c8e682392..000000000000 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - - bttv-i2c.c -- all the i2c code is here - - bttv - Bt848 frame grabber driver - - Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) - & Marcus Metzler (mocm@thp.uni-koeln.de) - (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> - - (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org> - - Multituner support and i2c address binding - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> - -#include "bttvp.h" -#include <media/v4l2-common.h> -#include <linux/jiffies.h> -#include <asm/io.h> - -static int i2c_debug; -static int i2c_hw; -static int i2c_scan; -module_param(i2c_debug, int, 0644); -MODULE_PARM_DESC(i2c_debug, "configure i2c debug level"); -module_param(i2c_hw, int, 0444); -MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, " - "instead of software bitbang"); -module_param(i2c_scan, int, 0444); -MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); - -static unsigned int i2c_udelay = 5; -module_param(i2c_udelay, int, 0444); -MODULE_PARM_DESC(i2c_udelay,"soft i2c delay at insmod time, in usecs " - "(should be 5 or higher). Lower value means higher bus speed."); - -/* ----------------------------------------------------------------------- */ -/* I2C functions - bitbanging adapter (software i2c) */ - -static void bttv_bit_setscl(void *data, int state) -{ - struct bttv *btv = (struct bttv*)data; - - if (state) - btv->i2c_state |= 0x02; - else - btv->i2c_state &= ~0x02; - btwrite(btv->i2c_state, BT848_I2C); - btread(BT848_I2C); -} - -static void bttv_bit_setsda(void *data, int state) -{ - struct bttv *btv = (struct bttv*)data; - - if (state) - btv->i2c_state |= 0x01; - else - btv->i2c_state &= ~0x01; - btwrite(btv->i2c_state, BT848_I2C); - btread(BT848_I2C); -} - -static int bttv_bit_getscl(void *data) -{ - struct bttv *btv = (struct bttv*)data; - int state; - - state = btread(BT848_I2C) & 0x02 ? 1 : 0; - return state; -} - -static int bttv_bit_getsda(void *data) -{ - struct bttv *btv = (struct bttv*)data; - int state; - - state = btread(BT848_I2C) & 0x01; - return state; -} - -static struct i2c_algo_bit_data __devinitdata bttv_i2c_algo_bit_template = { - .setsda = bttv_bit_setsda, - .setscl = bttv_bit_setscl, - .getsda = bttv_bit_getsda, - .getscl = bttv_bit_getscl, - .udelay = 16, - .timeout = 200, -}; - -/* ----------------------------------------------------------------------- */ -/* I2C functions - hardware i2c */ - -static u32 functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL; -} - -static int -bttv_i2c_wait_done(struct bttv *btv) -{ - int rc = 0; - - /* timeout */ - if (wait_event_interruptible_timeout(btv->i2c_queue, - btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS) - rc = -EIO; - - if (btv->i2c_done & BT848_INT_RACK) - rc = 1; - btv->i2c_done = 0; - return rc; -} - -#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\ - BT848_I2C_SCL | BT848_I2C_SDA) - -static int -bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last) -{ - u32 xmit; - int retval,cnt; - - /* sanity checks */ - if (0 == msg->len) - return -EINVAL; - - /* start, address + first byte */ - xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW; - if (msg->len > 1 || !last) - xmit |= BT878_I2C_NOSTOP; - btwrite(xmit, BT848_I2C); - retval = bttv_i2c_wait_done(btv); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - if (i2c_debug) { - pr_cont(" <W %02x %02x", msg->addr << 1, msg->buf[0]); - } - - for (cnt = 1; cnt < msg->len; cnt++ ) { - /* following bytes */ - xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART; - if (cnt < msg->len-1 || !last) - xmit |= BT878_I2C_NOSTOP; - btwrite(xmit, BT848_I2C); - retval = bttv_i2c_wait_done(btv); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - if (i2c_debug) - pr_cont(" %02x", msg->buf[cnt]); - } - if (!(xmit & BT878_I2C_NOSTOP)) - pr_cont(">\n"); - return msg->len; - - eio: - retval = -EIO; - err: - if (i2c_debug) - pr_cont(" ERR: %d\n",retval); - return retval; -} - -static int -bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last) -{ - u32 xmit; - u32 cnt; - int retval; - - for (cnt = 0; cnt < msg->len; cnt++) { - xmit = (msg->addr << 25) | (1 << 24) | I2C_HW; - if (cnt < msg->len-1) - xmit |= BT848_I2C_W3B; - if (cnt < msg->len-1 || !last) - xmit |= BT878_I2C_NOSTOP; - if (cnt) - xmit |= BT878_I2C_NOSTART; - - if (i2c_debug) { - if (!(xmit & BT878_I2C_NOSTART)) - pr_cont(" <R %02x", (msg->addr << 1) +1); - } - - btwrite(xmit, BT848_I2C); - retval = bttv_i2c_wait_done(btv); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff; - if (i2c_debug) { - pr_cont(" =%02x", msg->buf[cnt]); - } - if (i2c_debug && !(xmit & BT878_I2C_NOSTOP)) - pr_cont(" >\n"); - } - - - return msg->len; - - eio: - retval = -EIO; - err: - if (i2c_debug) - pr_cont(" ERR: %d\n",retval); - return retval; -} - -static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) -{ - struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap); - struct bttv *btv = to_bttv(v4l2_dev); - int retval = 0; - int i; - - if (i2c_debug) - pr_debug("bt-i2c:"); - - btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT); - for (i = 0 ; i < num; i++) { - if (msgs[i].flags & I2C_M_RD) { - /* read */ - retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num); - if (retval < 0) - goto err; - } else { - /* write */ - retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num); - if (retval < 0) - goto err; - } - } - return num; - - err: - return retval; -} - -static const struct i2c_algorithm bttv_algo = { - .master_xfer = bttv_i2c_xfer, - .functionality = functionality, -}; - -/* ----------------------------------------------------------------------- */ -/* I2C functions - common stuff */ - -/* read I2C */ -int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) -{ - unsigned char buffer = 0; - - if (0 != btv->i2c_rc) - return -1; - if (bttv_verbose && NULL != probe_for) - pr_info("%d: i2c: checking for %s @ 0x%02x... ", - btv->c.nr, probe_for, addr); - btv->i2c_client.addr = addr >> 1; - if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { - if (NULL != probe_for) { - if (bttv_verbose) - pr_cont("not found\n"); - } else - pr_warn("%d: i2c read 0x%x: error\n", - btv->c.nr, addr); - return -1; - } - if (bttv_verbose && NULL != probe_for) - pr_cont("found\n"); - return buffer; -} - -/* write I2C */ -int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, - unsigned char b2, int both) -{ - unsigned char buffer[2]; - int bytes = both ? 2 : 1; - - if (0 != btv->i2c_rc) - return -1; - btv->i2c_client.addr = addr >> 1; - buffer[0] = b1; - buffer[1] = b2; - if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) - return -1; - return 0; -} - -/* read EEPROM content */ -void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) -{ - memset(eedata, 0, 256); - if (0 != btv->i2c_rc) - return; - btv->i2c_client.addr = addr >> 1; - tveeprom_read(&btv->i2c_client, eedata, 256); -} - -static char *i2c_devs[128] = { - [ 0x1c >> 1 ] = "lgdt330x", - [ 0x30 >> 1 ] = "IR (hauppauge)", - [ 0x80 >> 1 ] = "msp34xx", - [ 0x86 >> 1 ] = "tda9887", - [ 0xa0 >> 1 ] = "eeprom", - [ 0xc0 >> 1 ] = "tuner (analog)", - [ 0xc2 >> 1 ] = "tuner (analog)", -}; - -static void do_i2c_scan(char *name, struct i2c_client *c) -{ - unsigned char buf; - int i,rc; - - for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { - c->addr = i; - rc = i2c_master_recv(c,&buf,0); - if (rc < 0) - continue; - pr_info("%s: i2c scan: found device @ 0x%x [%s]\n", - name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); - } -} - -/* init + register i2c adapter */ -int __devinit init_bttv_i2c(struct bttv *btv) -{ - strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE); - - if (i2c_hw) - btv->use_i2c_hw = 1; - if (btv->use_i2c_hw) { - /* bt878 */ - strlcpy(btv->c.i2c_adap.name, "bt878", - sizeof(btv->c.i2c_adap.name)); - btv->c.i2c_adap.algo = &bttv_algo; - } else { - /* bt848 */ - /* Prevents usage of invalid delay values */ - if (i2c_udelay<5) - i2c_udelay=5; - - strlcpy(btv->c.i2c_adap.name, "bttv", - sizeof(btv->c.i2c_adap.name)); - memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template, - sizeof(bttv_i2c_algo_bit_template)); - btv->i2c_algo.udelay = i2c_udelay; - btv->i2c_algo.data = btv; - btv->c.i2c_adap.algo_data = &btv->i2c_algo; - } - btv->c.i2c_adap.owner = THIS_MODULE; - - btv->c.i2c_adap.dev.parent = &btv->c.pci->dev; - snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name), - "bt%d #%d [%s]", btv->id, btv->c.nr, - btv->use_i2c_hw ? "hw" : "sw"); - - i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev); - btv->i2c_client.adapter = &btv->c.i2c_adap; - - - if (btv->use_i2c_hw) { - btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); - } else { - bttv_bit_setscl(btv,1); - bttv_bit_setsda(btv,1); - btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap); - } - if (0 == btv->i2c_rc && i2c_scan) - do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); - - return btv->i2c_rc; -} diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/video/bt8xx/bttv-if.c deleted file mode 100644 index a6a540dc9e4b..000000000000 --- a/drivers/media/video/bt8xx/bttv-if.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - - bttv-if.c -- old gpio interface to other kernel modules - don't use in new code, will go away in 2.7 - have a look at bttv-gpio.c instead. - - bttv - Bt848 frame grabber driver - - Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) - & Marcus Metzler (mocm@thp.uni-koeln.de) - (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <asm/io.h> - -#include "bttvp.h" - -EXPORT_SYMBOL(bttv_get_pcidev); -EXPORT_SYMBOL(bttv_gpio_enable); -EXPORT_SYMBOL(bttv_read_gpio); -EXPORT_SYMBOL(bttv_write_gpio); - -/* ----------------------------------------------------------------------- */ -/* Exported functions - for other modules which want to access the */ -/* gpio ports (IR for example) */ -/* see bttv.h for comments */ - -struct pci_dev* bttv_get_pcidev(unsigned int card) -{ - if (card >= bttv_num) - return NULL; - if (!bttvs[card]) - return NULL; - - return bttvs[card]->c.pci; -} - - -int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data) -{ - struct bttv *btv; - - if (card >= bttv_num) { - return -EINVAL; - } - - btv = bttvs[card]; - if (!btv) - return -ENODEV; - - gpio_inout(mask,data); - if (bttv_gpio) - bttv_gpio_tracking(btv,"extern enable"); - return 0; -} - -int bttv_read_gpio(unsigned int card, unsigned long *data) -{ - struct bttv *btv; - - if (card >= bttv_num) { - return -EINVAL; - } - - btv = bttvs[card]; - if (!btv) - return -ENODEV; - - if(btv->shutdown) { - return -ENODEV; - } - -/* prior setting BT848_GPIO_REG_INP is (probably) not needed - because we set direct input on init */ - *data = gpio_read(); - return 0; -} - -int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data) -{ - struct bttv *btv; - - if (card >= bttv_num) { - return -EINVAL; - } - - btv = bttvs[card]; - if (!btv) - return -ENODEV; - -/* prior setting BT848_GPIO_REG_INP is (probably) not needed - because direct input is set on init */ - gpio_bits(mask,data); - if (bttv_gpio) - bttv_gpio_tracking(btv,"extern write"); - return 0; -} - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c deleted file mode 100644 index ef4c7cd41982..000000000000 --- a/drivers/media/video/bt8xx/bttv-input.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * - * Copyright (c) 2003 Gerd Knorr - * Copyright (c) 2003 Pavel Machek - * - * 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 - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/input.h> -#include <linux/slab.h> - -#include "bttv.h" -#include "bttvp.h" - - -static int ir_debug; -module_param(ir_debug, int, 0644); - -static int ir_rc5_remote_gap = 885; -module_param(ir_rc5_remote_gap, int, 0644); - -#undef dprintk -#define dprintk(fmt, ...) \ -do { \ - if (ir_debug >= 1) \ - pr_info(fmt, ##__VA_ARGS__); \ -} while (0) - -#define DEVNAME "bttv-input" - -#define MODULE_NAME "bttv" - -/* ---------------------------------------------------------------------- */ - -static void ir_handle_key(struct bttv *btv) -{ - struct bttv_ir *ir = btv->remote; - u32 gpio,data; - - /* read gpio value */ - gpio = bttv_gpio_read(&btv->c); - if (ir->polling) { - if (ir->last_gpio == gpio) - return; - ir->last_gpio = gpio; - } - - /* extract data */ - data = ir_extract_bits(gpio, ir->mask_keycode); - dprintk("irq gpio=0x%x code=%d | %s%s%s\n", - gpio, data, - ir->polling ? "poll" : "irq", - (gpio & ir->mask_keydown) ? " down" : "", - (gpio & ir->mask_keyup) ? " up" : ""); - - if ((ir->mask_keydown && (gpio & ir->mask_keydown)) || - (ir->mask_keyup && !(gpio & ir->mask_keyup))) { - rc_keydown_notimeout(ir->dev, data, 0); - } else { - /* HACK: Probably, ir->mask_keydown is missing - for this board */ - if (btv->c.type == BTTV_BOARD_WINFAST2000) - rc_keydown_notimeout(ir->dev, data, 0); - - rc_keyup(ir->dev); - } -} - -static void ir_enltv_handle_key(struct bttv *btv) -{ - struct bttv_ir *ir = btv->remote; - u32 gpio, data, keyup; - - /* read gpio value */ - gpio = bttv_gpio_read(&btv->c); - - /* extract data */ - data = ir_extract_bits(gpio, ir->mask_keycode); - - /* Check if it is keyup */ - keyup = (gpio & ir->mask_keyup) ? 1 << 31 : 0; - - if ((ir->last_gpio & 0x7f) != data) { - dprintk("gpio=0x%x code=%d | %s\n", - gpio, data, - (gpio & ir->mask_keyup) ? " up" : "up/down"); - - rc_keydown_notimeout(ir->dev, data, 0); - if (keyup) - rc_keyup(ir->dev); - } else { - if ((ir->last_gpio & 1 << 31) == keyup) - return; - - dprintk("(cnt) gpio=0x%x code=%d | %s\n", - gpio, data, - (gpio & ir->mask_keyup) ? " up" : "down"); - - if (keyup) - rc_keyup(ir->dev); - else - rc_keydown_notimeout(ir->dev, data, 0); - } - - ir->last_gpio = data | keyup; -} - -static int bttv_rc5_irq(struct bttv *btv); - -void bttv_input_irq(struct bttv *btv) -{ - struct bttv_ir *ir = btv->remote; - - if (ir->rc5_gpio) - bttv_rc5_irq(btv); - else if (!ir->polling) - ir_handle_key(btv); -} - -static void bttv_input_timer(unsigned long data) -{ - struct bttv *btv = (struct bttv*)data; - struct bttv_ir *ir = btv->remote; - - if (btv->c.type == BTTV_BOARD_ENLTV_FM_2) - ir_enltv_handle_key(btv); - else - ir_handle_key(btv); - mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); -} - -/* - * FIXME: Nebula digi uses the legacy way to decode RC5, instead of relying - * on the rc-core way. As we need to be sure that both IRQ transitions are - * properly triggered, Better to touch it only with this hardware for - * testing. - */ - -#define RC5_START(x) (((x) >> 12) & 3) -#define RC5_TOGGLE(x) (((x) >> 11) & 1) -#define RC5_ADDR(x) (((x) >> 6) & 31) -#define RC5_INSTR(x) ((x) & 63) - -/* decode raw bit pattern to RC5 code */ -static u32 bttv_rc5_decode(unsigned int code) -{ - unsigned int org_code = code; - unsigned int pair; - unsigned int rc5 = 0; - int i; - - for (i = 0; i < 14; ++i) { - pair = code & 0x3; - code >>= 2; - - rc5 <<= 1; - switch (pair) { - case 0: - case 2: - break; - case 1: - rc5 |= 1; - break; - case 3: - dprintk("rc5_decode(%x) bad code\n", - org_code); - return 0; - } - } - dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " - "instr=%x\n", rc5, org_code, RC5_START(rc5), - RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); - return rc5; -} - -static void bttv_rc5_timer_end(unsigned long data) -{ - struct bttv_ir *ir = (struct bttv_ir *)data; - struct timeval tv; - u32 gap; - u32 rc5 = 0; - - /* get time */ - do_gettimeofday(&tv); - - /* avoid overflow with gap >1s */ - if (tv.tv_sec - ir->base_time.tv_sec > 1) { - gap = 200000; - } else { - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; - } - - /* signal we're ready to start a new code */ - ir->active = false; - - /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ - if (gap < 28000) { - dprintk("spurious timer_end\n"); - return; - } - - if (ir->last_bit < 20) { - /* ignore spurious codes (caused by light/other remotes) */ - dprintk("short code: %x\n", ir->code); - } else { - ir->code = (ir->code << ir->shift_by) | 1; - rc5 = bttv_rc5_decode(ir->code); - - /* two start bits? */ - if (RC5_START(rc5) != ir->start) { - pr_info(DEVNAME ":" - " rc5 start bits invalid: %u\n", RC5_START(rc5)); - - /* right address? */ - } else if (RC5_ADDR(rc5) == ir->addr) { - u32 toggle = RC5_TOGGLE(rc5); - u32 instr = RC5_INSTR(rc5); - - /* Good code */ - rc_keydown(ir->dev, instr, toggle); - dprintk("instruction %x, toggle %x\n", - instr, toggle); - } - } -} - -static int bttv_rc5_irq(struct bttv *btv) -{ - struct bttv_ir *ir = btv->remote; - struct timeval tv; - u32 gpio; - u32 gap; - unsigned long current_jiffies; - - /* read gpio port */ - gpio = bttv_gpio_read(&btv->c); - - /* get time of bit */ - current_jiffies = jiffies; - do_gettimeofday(&tv); - - /* avoid overflow with gap >1s */ - if (tv.tv_sec - ir->base_time.tv_sec > 1) { - gap = 200000; - } else { - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; - } - - dprintk("RC5 IRQ: gap %d us for %s\n", - gap, (gpio & 0x20) ? "mark" : "space"); - - /* remote IRQ? */ - if (!(gpio & 0x20)) - return 0; - - /* active code => add bit */ - if (ir->active) { - /* only if in the code (otherwise spurious IRQ or timer - late) */ - if (ir->last_bit < 28) { - ir->last_bit = (gap - ir_rc5_remote_gap / 2) / - ir_rc5_remote_gap; - ir->code |= 1 << ir->last_bit; - } - /* starting new code */ - } else { - ir->active = true; - ir->code = 0; - ir->base_time = tv; - ir->last_bit = 0; - - mod_timer(&ir->timer, current_jiffies + msecs_to_jiffies(30)); - } - - /* toggle GPIO pin 4 to reset the irq */ - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); - bttv_gpio_write(&btv->c, gpio | (1 << 4)); - return 1; -} - -/* ---------------------------------------------------------------------- */ - -static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir) -{ - if (ir->polling) { - setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv); - ir->timer.expires = jiffies + msecs_to_jiffies(1000); - add_timer(&ir->timer); - } else if (ir->rc5_gpio) { - /* set timer_end for code completion */ - setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir); - ir->shift_by = 1; - ir->start = 3; - ir->addr = 0x0; - ir->rc5_remote_gap = ir_rc5_remote_gap; - } -} - -static void bttv_ir_stop(struct bttv *btv) -{ - if (btv->remote->polling) - del_timer_sync(&btv->remote->timer); - - if (btv->remote->rc5_gpio) { - u32 gpio; - - del_timer_sync(&btv->remote->timer); - - gpio = bttv_gpio_read(&btv->c); - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); - } -} - -/* - * Get_key functions used by I2C remotes - */ - -static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) -{ - unsigned char b; - - /* poll IR chip */ - if (1 != i2c_master_recv(ir->c, &b, 1)) { - dprintk("read error\n"); - return -EIO; - } - - /* ignore 0xaa */ - if (b==0xaa) - return 0; - dprintk("key %02x\n", b); - - /* - * NOTE: - * lirc_i2c maps the pv951 code as: - * addr = 0x61D6 - * cmd = bit_reverse (b) - * So, it seems that this device uses NEC extended - * I decided to not fix the table, due to two reasons: - * 1) Without the actual device, this is only a guess; - * 2) As the addr is not reported via I2C, nor can be changed, - * the device is bound to the vendor-provided RC. - */ - - *ir_key = b; - *ir_raw = b; - return 1; -} - -/* Instantiate the I2C IR receiver device, if present */ -void __devinit init_bttv_i2c_ir(struct bttv *btv) -{ - const unsigned short addr_list[] = { - 0x1a, 0x18, 0x64, 0x30, 0x71, - I2C_CLIENT_END - }; - struct i2c_board_info info; - - if (0 != btv->i2c_rc) - return; - - memset(&info, 0, sizeof(struct i2c_board_info)); - memset(&btv->init_data, 0, sizeof(btv->init_data)); - strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - - switch (btv->c.type) { - case BTTV_BOARD_PV951: - btv->init_data.name = "PV951"; - btv->init_data.get_key = get_key_pv951; - btv->init_data.ir_codes = RC_MAP_PV951; - info.addr = 0x4b; - break; - default: - /* - * The external IR receiver is at i2c address 0x34 (0x35 for - * reads). Future Hauppauge cards will have an internal - * receiver at 0x30 (0x31 for reads). In theory, both can be - * fitted, and Hauppauge suggest an external overrides an - * internal. - * That's why we probe 0x1a (~0x34) first. CB - */ - - i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL); - return; - } - - if (btv->init_data.name) - info.platform_data = &btv->init_data; - i2c_new_device(&btv->c.i2c_adap, &info); - - return; -} - -int __devexit fini_bttv_i2c(struct bttv *btv) -{ - if (0 != btv->i2c_rc) - return 0; - - return i2c_del_adapter(&btv->c.i2c_adap); -} - -int bttv_input_init(struct bttv *btv) -{ - struct bttv_ir *ir; - char *ir_codes = NULL; - struct rc_dev *rc; - int err = -ENOMEM; - - if (!btv->has_remote) - return -ENODEV; - - ir = kzalloc(sizeof(*ir),GFP_KERNEL); - rc = rc_allocate_device(); - if (!ir || !rc) - goto err_out_free; - - /* detect & configure */ - switch (btv->c.type) { - case BTTV_BOARD_AVERMEDIA: - case BTTV_BOARD_AVPHONE98: - case BTTV_BOARD_AVERMEDIA98: - ir_codes = RC_MAP_AVERMEDIA; - ir->mask_keycode = 0xf88000; - ir->mask_keydown = 0x010000; - ir->polling = 50; // ms - break; - - case BTTV_BOARD_AVDVBT_761: - case BTTV_BOARD_AVDVBT_771: - ir_codes = RC_MAP_AVERMEDIA_DVBT; - ir->mask_keycode = 0x0f00c0; - ir->mask_keydown = 0x000020; - ir->polling = 50; // ms - break; - - case BTTV_BOARD_PXELVWPLTVPAK: - ir_codes = RC_MAP_PIXELVIEW; - ir->mask_keycode = 0x003e00; - ir->mask_keyup = 0x010000; - ir->polling = 50; // ms - break; - case BTTV_BOARD_PV_M4900: - case BTTV_BOARD_PV_BT878P_9B: - case BTTV_BOARD_PV_BT878P_PLUS: - ir_codes = RC_MAP_PIXELVIEW; - ir->mask_keycode = 0x001f00; - ir->mask_keyup = 0x008000; - ir->polling = 50; // ms - break; - - case BTTV_BOARD_WINFAST2000: - ir_codes = RC_MAP_WINFAST; - ir->mask_keycode = 0x1f8; - break; - case BTTV_BOARD_MAGICTVIEW061: - case BTTV_BOARD_MAGICTVIEW063: - ir_codes = RC_MAP_WINFAST; - ir->mask_keycode = 0x0008e000; - ir->mask_keydown = 0x00200000; - break; - case BTTV_BOARD_APAC_VIEWCOMP: - ir_codes = RC_MAP_APAC_VIEWCOMP; - ir->mask_keycode = 0x001f00; - ir->mask_keyup = 0x008000; - ir->polling = 50; // ms - break; - case BTTV_BOARD_ASKEY_CPH03X: - case BTTV_BOARD_CONCEPTRONIC_CTVFMI2: - case BTTV_BOARD_CONTVFMI: - ir_codes = RC_MAP_PIXELVIEW; - ir->mask_keycode = 0x001F00; - ir->mask_keyup = 0x006000; - ir->polling = 50; // ms - break; - case BTTV_BOARD_NEBULA_DIGITV: - ir_codes = RC_MAP_NEBULA; - ir->rc5_gpio = true; - break; - case BTTV_BOARD_MACHTV_MAGICTV: - ir_codes = RC_MAP_APAC_VIEWCOMP; - ir->mask_keycode = 0x001F00; - ir->mask_keyup = 0x004000; - ir->polling = 50; /* ms */ - break; - case BTTV_BOARD_KOZUMI_KTV_01C: - ir_codes = RC_MAP_PCTV_SEDNA; - ir->mask_keycode = 0x001f00; - ir->mask_keyup = 0x006000; - ir->polling = 50; /* ms */ - break; - case BTTV_BOARD_ENLTV_FM_2: - ir_codes = RC_MAP_ENCORE_ENLTV2; - ir->mask_keycode = 0x00fd00; - ir->mask_keyup = 0x000080; - ir->polling = 1; /* ms */ - ir->last_gpio = ir_extract_bits(bttv_gpio_read(&btv->c), - ir->mask_keycode); - break; - } - if (NULL == ir_codes) { - dprintk("Ooops: IR config error [card=%d]\n", btv->c.type); - err = -ENODEV; - goto err_out_free; - } - - if (ir->rc5_gpio) { - u32 gpio; - /* enable remote irq */ - bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); - gpio = bttv_gpio_read(&btv->c); - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); - bttv_gpio_write(&btv->c, gpio | (1 << 4)); - } else { - /* init hardware-specific stuff */ - bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0); - } - - /* init input device */ - ir->dev = rc; - - snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", - btv->c.type); - snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", - pci_name(btv->c.pci)); - - rc->input_name = ir->name; - rc->input_phys = ir->phys; - rc->input_id.bustype = BUS_PCI; - rc->input_id.version = 1; - if (btv->c.pci->subsystem_vendor) { - rc->input_id.vendor = btv->c.pci->subsystem_vendor; - rc->input_id.product = btv->c.pci->subsystem_device; - } else { - rc->input_id.vendor = btv->c.pci->vendor; - rc->input_id.product = btv->c.pci->device; - } - rc->dev.parent = &btv->c.pci->dev; - rc->map_name = ir_codes; - rc->driver_name = MODULE_NAME; - - btv->remote = ir; - bttv_ir_start(btv, ir); - - /* all done */ - err = rc_register_device(rc); - if (err) - goto err_out_stop; - - return 0; - - err_out_stop: - bttv_ir_stop(btv); - btv->remote = NULL; - err_out_free: - rc_free_device(rc); - kfree(ir); - return err; -} - -void bttv_input_fini(struct bttv *btv) -{ - if (btv->remote == NULL) - return; - - bttv_ir_stop(btv); - rc_unregister_device(btv->remote->dev); - kfree(btv->remote); - btv->remote = NULL; -} diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c deleted file mode 100644 index 82cc47d2e3fa..000000000000 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ /dev/null @@ -1,909 +0,0 @@ -/* - - bttv-risc.c -- interfaces to other kernel modules - - bttv risc code handling - - memory management - - generation - - (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org> - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/pci.h> -#include <linux/vmalloc.h> -#include <linux/interrupt.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <media/v4l2-ioctl.h> - -#include "bttvp.h" - -#define VCR_HACK_LINES 4 - -/* ---------------------------------------------------------- */ -/* risc code generators */ - -int -bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, - struct scatterlist *sglist, - unsigned int offset, unsigned int bpl, - unsigned int padding, unsigned int skip_lines, - unsigned int store_lines) -{ - u32 instructions,line,todo; - struct scatterlist *sg; - __le32 *rp; - int rc; - - /* estimate risc mem: worst case is one write per page border + - one write per scan line + sync + jump (all 2 dwords). padding - can cause next bpl to start close to a page border. First DMA - region may be smaller than PAGE_SIZE */ - instructions = skip_lines * 4; - instructions += (1 + ((bpl + padding) * store_lines) - / PAGE_SIZE + store_lines) * 8; - instructions += 2 * 8; - if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0) - return rc; - - /* sync instruction */ - rp = risc->cpu; - *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); - *(rp++) = cpu_to_le32(0); - - while (skip_lines-- > 0) { - *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL | - BT848_RISC_EOL | bpl); - } - - /* scan lines */ - sg = sglist; - for (line = 0; line < store_lines; line++) { - if ((btv->opt_vcr_hack) && - (line >= (store_lines - VCR_HACK_LINES))) - continue; - while (offset && offset >= sg_dma_len(sg)) { - offset -= sg_dma_len(sg); - sg++; - } - if (bpl <= sg_dma_len(sg)-offset) { - /* fits into current chunk */ - *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| - BT848_RISC_EOL|bpl); - *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); - offset+=bpl; - } else { - /* scanline needs to be splitted */ - todo = bpl; - *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| - (sg_dma_len(sg)-offset)); - *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); - todo -= (sg_dma_len(sg)-offset); - offset = 0; - sg++; - while (todo > sg_dma_len(sg)) { - *(rp++)=cpu_to_le32(BT848_RISC_WRITE| - sg_dma_len(sg)); - *(rp++)=cpu_to_le32(sg_dma_address(sg)); - todo -= sg_dma_len(sg); - sg++; - } - *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL| - todo); - *(rp++)=cpu_to_le32(sg_dma_address(sg)); - offset += todo; - } - offset += padding; - } - - /* save pointer to jmp instruction address */ - risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); - return 0; -} - -static int -bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, - struct scatterlist *sglist, - unsigned int yoffset, unsigned int ybpl, - unsigned int ypadding, unsigned int ylines, - unsigned int uoffset, unsigned int voffset, - unsigned int hshift, unsigned int vshift, - unsigned int cpadding) -{ - unsigned int instructions,line,todo,ylen,chroma; - __le32 *rp; - u32 ri; - struct scatterlist *ysg; - struct scatterlist *usg; - struct scatterlist *vsg; - int topfield = (0 == yoffset); - int rc; - - /* estimate risc mem: worst case is one write per page border + - one write per scan line (5 dwords) - plus sync + jump (2 dwords) */ - instructions = ((3 + (ybpl + ypadding) * ylines * 2) - / PAGE_SIZE) + ylines; - instructions += 2; - if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0) - return rc; - - /* sync instruction */ - rp = risc->cpu; - *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3); - *(rp++) = cpu_to_le32(0); - - /* scan lines */ - ysg = sglist; - usg = sglist; - vsg = sglist; - for (line = 0; line < ylines; line++) { - if ((btv->opt_vcr_hack) && - (line >= (ylines - VCR_HACK_LINES))) - continue; - switch (vshift) { - case 0: - chroma = 1; - break; - case 1: - if (topfield) - chroma = ((line & 1) == 0); - else - chroma = ((line & 1) == 1); - break; - case 2: - if (topfield) - chroma = ((line & 3) == 0); - else - chroma = ((line & 3) == 2); - break; - default: - chroma = 0; - break; - } - - for (todo = ybpl; todo > 0; todo -= ylen) { - /* go to next sg entry if needed */ - while (yoffset && yoffset >= sg_dma_len(ysg)) { - yoffset -= sg_dma_len(ysg); - ysg++; - } - while (uoffset && uoffset >= sg_dma_len(usg)) { - uoffset -= sg_dma_len(usg); - usg++; - } - while (voffset && voffset >= sg_dma_len(vsg)) { - voffset -= sg_dma_len(vsg); - vsg++; - } - - /* calculate max number of bytes we can write */ - ylen = todo; - if (yoffset + ylen > sg_dma_len(ysg)) - ylen = sg_dma_len(ysg) - yoffset; - if (chroma) { - if (uoffset + (ylen>>hshift) > sg_dma_len(usg)) - ylen = (sg_dma_len(usg) - uoffset) << hshift; - if (voffset + (ylen>>hshift) > sg_dma_len(vsg)) - ylen = (sg_dma_len(vsg) - voffset) << hshift; - ri = BT848_RISC_WRITE123; - } else { - ri = BT848_RISC_WRITE1S23; - } - if (ybpl == todo) - ri |= BT848_RISC_SOL; - if (ylen == todo) - ri |= BT848_RISC_EOL; - - /* write risc instruction */ - *(rp++)=cpu_to_le32(ri | ylen); - *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) | - (ylen >> hshift)); - *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset); - yoffset += ylen; - if (chroma) { - *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset); - uoffset += ylen >> hshift; - *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset); - voffset += ylen >> hshift; - } - } - yoffset += ypadding; - if (chroma) { - uoffset += cpadding; - voffset += cpadding; - } - } - - /* save pointer to jmp instruction address */ - risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); - return 0; -} - -static int -bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, - const struct bttv_format *fmt, struct bttv_overlay *ov, - int skip_even, int skip_odd) -{ - int dwords, rc, line, maxy, start, end; - unsigned skip, nskips; - struct btcx_skiplist *skips; - __le32 *rp; - u32 ri,ra; - u32 addr; - - /* skip list for window clipping */ - if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL))) - return -ENOMEM; - - /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions - + sync + jump (all 2 dwords) */ - dwords = (3 * ov->nclips + 2) * - ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height); - dwords += 4; - if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) { - kfree(skips); - return rc; - } - - /* sync instruction */ - rp = risc->cpu; - *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); - *(rp++) = cpu_to_le32(0); - - addr = (unsigned long)btv->fbuf.base; - addr += btv->fbuf.fmt.bytesperline * ov->w.top; - addr += (fmt->depth >> 3) * ov->w.left; - - /* scan lines */ - for (maxy = -1, line = 0; line < ov->w.height; - line++, addr += btv->fbuf.fmt.bytesperline) { - if ((btv->opt_vcr_hack) && - (line >= (ov->w.height - VCR_HACK_LINES))) - continue; - if ((line%2) == 0 && skip_even) - continue; - if ((line%2) == 1 && skip_odd) - continue; - - /* calculate clipping */ - if (line > maxy) - btcx_calc_skips(line, ov->w.width, &maxy, - skips, &nskips, ov->clips, ov->nclips); - - /* write out risc code */ - for (start = 0, skip = 0; start < ov->w.width; start = end) { - if (skip >= nskips) { - ri = BT848_RISC_WRITE; - end = ov->w.width; - } else if (start < skips[skip].start) { - ri = BT848_RISC_WRITE; - end = skips[skip].start; - } else { - ri = BT848_RISC_SKIP; - end = skips[skip].end; - skip++; - } - if (BT848_RISC_WRITE == ri) - ra = addr + (fmt->depth>>3)*start; - else - ra = 0; - - if (0 == start) - ri |= BT848_RISC_SOL; - if (ov->w.width == end) - ri |= BT848_RISC_EOL; - ri |= (fmt->depth>>3) * (end-start); - - *(rp++)=cpu_to_le32(ri); - if (0 != ra) - *(rp++)=cpu_to_le32(ra); - } - } - - /* save pointer to jmp instruction address */ - risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); - kfree(skips); - return 0; -} - -/* ---------------------------------------------------------- */ - -static void -bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo, - int width, int height, int interleaved, - const struct bttv_tvnorm *tvnorm) -{ - u32 xsf, sr; - int vdelay; - - int swidth = tvnorm->swidth; - int totalwidth = tvnorm->totalwidth; - int scaledtwidth = tvnorm->scaledtwidth; - - if (btv->input == btv->dig) { - swidth = 720; - totalwidth = 858; - scaledtwidth = 858; - } - - vdelay = tvnorm->vdelay; - - xsf = (width*scaledtwidth)/swidth; - geo->hscale = ((totalwidth*4096UL)/xsf-4096); - geo->hdelay = tvnorm->hdelayx1; - geo->hdelay = (geo->hdelay*width)/swidth; - geo->hdelay &= 0x3fe; - sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; - geo->vscale = (0x10000UL-sr) & 0x1fff; - geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | - ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); - geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; - geo->vdelay = vdelay; - geo->width = width; - geo->sheight = tvnorm->sheight; - geo->vtotal = tvnorm->vtotal; - - if (btv->opt_combfilter) { - geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); - geo->comb = (width < 769) ? 1 : 0; - } else { - geo->vtc = 0; - geo->comb = 0; - } -} - -static void -bttv_calc_geo (struct bttv * btv, - struct bttv_geometry * geo, - unsigned int width, - unsigned int height, - int both_fields, - const struct bttv_tvnorm * tvnorm, - const struct v4l2_rect * crop) -{ - unsigned int c_width; - unsigned int c_height; - u32 sr; - - if ((crop->left == tvnorm->cropcap.defrect.left - && crop->top == tvnorm->cropcap.defrect.top - && crop->width == tvnorm->cropcap.defrect.width - && crop->height == tvnorm->cropcap.defrect.height - && width <= tvnorm->swidth /* see PAL-Nc et al */) - || btv->input == btv->dig) { - bttv_calc_geo_old(btv, geo, width, height, - both_fields, tvnorm); - return; - } - - /* For bug compatibility the image size checks permit scale - factors > 16. See bttv_crop_calc_limits(). */ - c_width = min((unsigned int) crop->width, width * 16); - c_height = min((unsigned int) crop->height, height * 16); - - geo->width = width; - geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096; - /* Even to store Cb first, odd for Cr. */ - geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1; - - geo->sheight = c_height; - geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY; - sr = c_height >> !both_fields; - sr = (sr * 512U + (height >> 1)) / height - 512; - geo->vscale = (0x10000UL - sr) & 0x1fff; - geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0; - geo->vtotal = tvnorm->vtotal; - - geo->crop = (((geo->width >> 8) & 0x03) | - ((geo->hdelay >> 6) & 0x0c) | - ((geo->sheight >> 4) & 0x30) | - ((geo->vdelay >> 2) & 0xc0)); - - if (btv->opt_combfilter) { - geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); - geo->comb = (width < 769) ? 1 : 0; - } else { - geo->vtc = 0; - geo->comb = 0; - } -} - -static void -bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) -{ - int off = odd ? 0x80 : 0x00; - - if (geo->comb) - btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); - else - btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); - - btwrite(geo->vtc, BT848_E_VTC+off); - btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); - btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); - btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); - btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); - btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); - btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); - btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); - btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); - btwrite(geo->crop, BT848_E_CROP+off); - btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); - btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); -} - -/* ---------------------------------------------------------- */ -/* risc group / risc main loop / dma management */ - -void -bttv_set_dma(struct bttv *btv, int override) -{ - unsigned long cmd; - int capctl; - - btv->cap_ctl = 0; - if (NULL != btv->curr.top) btv->cap_ctl |= 0x02; - if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01; - if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c; - - capctl = 0; - capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */ - capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */ - capctl |= override; - - d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n", - btv->c.nr,capctl,btv->loop_irq, - btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, - btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, - btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0, - btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); - - cmd = BT848_RISC_JUMP; - if (btv->loop_irq) { - cmd |= BT848_RISC_IRQ; - cmd |= (btv->loop_irq & 0x0f) << 16; - cmd |= (~btv->loop_irq & 0x0f) << 20; - } - if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) { - mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT); - } else { - del_timer(&btv->timeout); - } - btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); - - btaor(capctl, ~0x0f, BT848_CAP_CTL); - if (capctl) { - if (btv->dma_on) - return; - btwrite(btv->main.dma, BT848_RISC_STRT_ADD); - btor(3, BT848_GPIO_DMA_CTL); - btv->dma_on = 1; - } else { - if (!btv->dma_on) - return; - btand(~3, BT848_GPIO_DMA_CTL); - btv->dma_on = 0; - } - return; -} - -int -bttv_risc_init_main(struct bttv *btv) -{ - int rc; - - if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0) - return rc; - dprintk("%d: risc main @ %08llx\n", - btv->c.nr, (unsigned long long)btv->main.dma); - - btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | - BT848_FIFO_STATUS_VRE); - btv->main.cpu[1] = cpu_to_le32(0); - btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP); - btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2)); - - /* top field */ - btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP); - btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2)); - btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); - btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); - - btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | - BT848_FIFO_STATUS_VRO); - btv->main.cpu[9] = cpu_to_le32(0); - - /* bottom field */ - btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); - btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); - btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); - btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); - - /* jump back to top field */ - btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); - btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); - - return 0; -} - -int -bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, - int irqflags) -{ - unsigned long cmd; - unsigned long next = btv->main.dma + ((slot+2) << 2); - - if (NULL == risc) { - d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot); - btv->main.cpu[slot+1] = cpu_to_le32(next); - } else { - d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n", - btv->c.nr, risc, slot, - (unsigned long long)risc->dma, irqflags); - cmd = BT848_RISC_JUMP; - if (irqflags) { - cmd |= BT848_RISC_IRQ; - cmd |= (irqflags & 0x0f) << 16; - cmd |= (~irqflags & 0x0f) << 20; - } - risc->jmp[0] = cpu_to_le32(cmd); - risc->jmp[1] = cpu_to_le32(next); - btv->main.cpu[slot+1] = cpu_to_le32(risc->dma); - } - return 0; -} - -void -bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf) -{ - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - - BUG_ON(in_interrupt()); - videobuf_waiton(q, &buf->vb, 0, 0); - videobuf_dma_unmap(q->dev, dma); - videobuf_dma_free(dma); - btcx_riscmem_free(btv->c.pci,&buf->bottom); - btcx_riscmem_free(btv->c.pci,&buf->top); - buf->vb.state = VIDEOBUF_NEEDS_INIT; -} - -int -bttv_buffer_activate_vbi(struct bttv *btv, - struct bttv_buffer *vbi) -{ - struct btcx_riscmem *top; - struct btcx_riscmem *bottom; - int top_irq_flags; - int bottom_irq_flags; - - top = NULL; - bottom = NULL; - top_irq_flags = 0; - bottom_irq_flags = 0; - - if (vbi) { - unsigned int crop, vdelay; - - vbi->vb.state = VIDEOBUF_ACTIVE; - list_del(&vbi->vb.queue); - - /* VDELAY is start of video, end of VBI capturing. */ - crop = btread(BT848_E_CROP); - vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2); - - if (vbi->geo.vdelay > vdelay) { - vdelay = vbi->geo.vdelay & 0xfe; - crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0); - - btwrite(vdelay, BT848_E_VDELAY_LO); - btwrite(crop, BT848_E_CROP); - btwrite(vdelay, BT848_O_VDELAY_LO); - btwrite(crop, BT848_O_CROP); - } - - if (vbi->vbi_count[0] > 0) { - top = &vbi->top; - top_irq_flags = 4; - } - - if (vbi->vbi_count[1] > 0) { - top_irq_flags = 0; - bottom = &vbi->bottom; - bottom_irq_flags = 4; - } - } - - bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags); - bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags); - - return 0; -} - -int -bttv_buffer_activate_video(struct bttv *btv, - struct bttv_buffer_set *set) -{ - /* video capture */ - if (NULL != set->top && NULL != set->bottom) { - if (set->top == set->bottom) { - set->top->vb.state = VIDEOBUF_ACTIVE; - if (set->top->vb.queue.next) - list_del(&set->top->vb.queue); - } else { - set->top->vb.state = VIDEOBUF_ACTIVE; - set->bottom->vb.state = VIDEOBUF_ACTIVE; - if (set->top->vb.queue.next) - list_del(&set->top->vb.queue); - if (set->bottom->vb.queue.next) - list_del(&set->bottom->vb.queue); - } - bttv_apply_geo(btv, &set->top->geo, 1); - bttv_apply_geo(btv, &set->bottom->geo,0); - bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, - set->top_irq); - bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, - set->frame_irq); - btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f), - ~0xff, BT848_COLOR_FMT); - btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05), - ~0x0f, BT848_COLOR_CTL); - } else if (NULL != set->top) { - set->top->vb.state = VIDEOBUF_ACTIVE; - if (set->top->vb.queue.next) - list_del(&set->top->vb.queue); - bttv_apply_geo(btv, &set->top->geo,1); - bttv_apply_geo(btv, &set->top->geo,0); - bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, - set->frame_irq); - bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); - btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT); - btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); - } else if (NULL != set->bottom) { - set->bottom->vb.state = VIDEOBUF_ACTIVE; - if (set->bottom->vb.queue.next) - list_del(&set->bottom->vb.queue); - bttv_apply_geo(btv, &set->bottom->geo,1); - bttv_apply_geo(btv, &set->bottom->geo,0); - bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); - bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, - set->frame_irq); - btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT); - btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); - } else { - bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); - bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); - } - return 0; -} - -/* ---------------------------------------------------------- */ - -/* calculate geometry, build risc code */ -int -bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) -{ - const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm; - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - - dprintk("%d: buffer field: %s format: %s size: %dx%d\n", - btv->c.nr, v4l2_field_names[buf->vb.field], - buf->fmt->name, buf->vb.width, buf->vb.height); - - /* packed pixel modes */ - if (buf->fmt->flags & FORMAT_FLAGS_PACKED) { - int bpl = (buf->fmt->depth >> 3) * buf->vb.width; - int bpf = bpl * (buf->vb.height >> 1); - - bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height, - V4L2_FIELD_HAS_BOTH(buf->vb.field), - tvnorm,&buf->crop); - - switch (buf->vb.field) { - case V4L2_FIELD_TOP: - bttv_risc_packed(btv,&buf->top,dma->sglist, - /* offset */ 0,bpl, - /* padding */ 0,/* skip_lines */ 0, - buf->vb.height); - break; - case V4L2_FIELD_BOTTOM: - bttv_risc_packed(btv,&buf->bottom,dma->sglist, - 0,bpl,0,0,buf->vb.height); - break; - case V4L2_FIELD_INTERLACED: - bttv_risc_packed(btv,&buf->top,dma->sglist, - 0,bpl,bpl,0,buf->vb.height >> 1); - bttv_risc_packed(btv,&buf->bottom,dma->sglist, - bpl,bpl,bpl,0,buf->vb.height >> 1); - break; - case V4L2_FIELD_SEQ_TB: - bttv_risc_packed(btv,&buf->top,dma->sglist, - 0,bpl,0,0,buf->vb.height >> 1); - bttv_risc_packed(btv,&buf->bottom,dma->sglist, - bpf,bpl,0,0,buf->vb.height >> 1); - break; - default: - BUG(); - } - } - - /* planar modes */ - if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) { - int uoffset, voffset; - int ypadding, cpadding, lines; - - /* calculate chroma offsets */ - uoffset = buf->vb.width * buf->vb.height; - voffset = buf->vb.width * buf->vb.height; - if (buf->fmt->flags & FORMAT_FLAGS_CrCb) { - /* Y-Cr-Cb plane order */ - uoffset >>= buf->fmt->hshift; - uoffset >>= buf->fmt->vshift; - uoffset += voffset; - } else { - /* Y-Cb-Cr plane order */ - voffset >>= buf->fmt->hshift; - voffset >>= buf->fmt->vshift; - voffset += uoffset; - } - - switch (buf->vb.field) { - case V4L2_FIELD_TOP: - bttv_calc_geo(btv,&buf->geo,buf->vb.width, - buf->vb.height,/* both_fields */ 0, - tvnorm,&buf->crop); - bttv_risc_planar(btv, &buf->top, dma->sglist, - 0,buf->vb.width,0,buf->vb.height, - uoffset,voffset,buf->fmt->hshift, - buf->fmt->vshift,0); - break; - case V4L2_FIELD_BOTTOM: - bttv_calc_geo(btv,&buf->geo,buf->vb.width, - buf->vb.height,0, - tvnorm,&buf->crop); - bttv_risc_planar(btv, &buf->bottom, dma->sglist, - 0,buf->vb.width,0,buf->vb.height, - uoffset,voffset,buf->fmt->hshift, - buf->fmt->vshift,0); - break; - case V4L2_FIELD_INTERLACED: - bttv_calc_geo(btv,&buf->geo,buf->vb.width, - buf->vb.height,1, - tvnorm,&buf->crop); - lines = buf->vb.height >> 1; - ypadding = buf->vb.width; - cpadding = buf->vb.width >> buf->fmt->hshift; - bttv_risc_planar(btv,&buf->top, - dma->sglist, - 0,buf->vb.width,ypadding,lines, - uoffset,voffset, - buf->fmt->hshift, - buf->fmt->vshift, - cpadding); - bttv_risc_planar(btv,&buf->bottom, - dma->sglist, - ypadding,buf->vb.width,ypadding,lines, - uoffset+cpadding, - voffset+cpadding, - buf->fmt->hshift, - buf->fmt->vshift, - cpadding); - break; - case V4L2_FIELD_SEQ_TB: - bttv_calc_geo(btv,&buf->geo,buf->vb.width, - buf->vb.height,1, - tvnorm,&buf->crop); - lines = buf->vb.height >> 1; - ypadding = buf->vb.width; - cpadding = buf->vb.width >> buf->fmt->hshift; - bttv_risc_planar(btv,&buf->top, - dma->sglist, - 0,buf->vb.width,0,lines, - uoffset >> 1, - voffset >> 1, - buf->fmt->hshift, - buf->fmt->vshift, - 0); - bttv_risc_planar(btv,&buf->bottom, - dma->sglist, - lines * ypadding,buf->vb.width,0,lines, - lines * ypadding + (uoffset >> 1), - lines * ypadding + (voffset >> 1), - buf->fmt->hshift, - buf->fmt->vshift, - 0); - break; - default: - BUG(); - } - } - - /* raw data */ - if (buf->fmt->flags & FORMAT_FLAGS_RAW) { - /* build risc code */ - buf->vb.field = V4L2_FIELD_SEQ_TB; - bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight, - 1,tvnorm,&buf->crop); - bttv_risc_packed(btv, &buf->top, dma->sglist, - /* offset */ 0, RAW_BPL, /* padding */ 0, - /* skip_lines */ 0, RAW_LINES); - bttv_risc_packed(btv, &buf->bottom, dma->sglist, - buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES); - } - - /* copy format info */ - buf->btformat = buf->fmt->btformat; - buf->btswap = buf->fmt->btswap; - return 0; -} - -/* ---------------------------------------------------------- */ - -/* calculate geometry, build risc code */ -int -bttv_overlay_risc(struct bttv *btv, - struct bttv_overlay *ov, - const struct bttv_format *fmt, - struct bttv_buffer *buf) -{ - /* check interleave, bottom+top fields */ - dprintk("%d: overlay fields: %s format: %s size: %dx%d\n", - btv->c.nr, v4l2_field_names[buf->vb.field], - fmt->name, ov->w.width, ov->w.height); - - /* calculate geometry */ - bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height, - V4L2_FIELD_HAS_BOTH(ov->field), - &bttv_tvnorms[ov->tvnorm],&buf->crop); - - /* build risc code */ - switch (ov->field) { - case V4L2_FIELD_TOP: - bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0); - break; - case V4L2_FIELD_BOTTOM: - bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0); - break; - case V4L2_FIELD_INTERLACED: - bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1); - bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0); - break; - default: - BUG(); - } - - /* copy format info */ - buf->btformat = fmt->btformat; - buf->btswap = fmt->btswap; - buf->vb.field = ov->field; - return 0; -} - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c deleted file mode 100644 index b433267d9aa9..000000000000 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - - bttv - Bt848 frame grabber driver - vbi interface - - (c) 2002 Gerd Knorr <kraxel@bytesex.org> - - Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> - Sponsored by OPQ Systems AB - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/kdev_t.h> -#include <media/v4l2-ioctl.h> -#include <asm/io.h> -#include "bttvp.h" - -/* Offset from line sync pulse leading edge (0H) to start of VBI capture, - in fCLKx2 pixels. According to the datasheet, VBI capture starts - VBI_HDELAY fCLKx1 pixels from the tailing edgeof /HRESET, and /HRESET - is 64 fCLKx1 pixels wide. VBI_HDELAY is set to 0, so this should be - (64 + 0) * 2 = 128 fCLKx2 pixels. But it's not! The datasheet is - Just Plain Wrong. The real value appears to be different for - different revisions of the bt8x8 chips, and to be affected by the - horizontal scaling factor. Experimentally, the value is measured - to be about 244. */ -#define VBI_OFFSET 244 - -/* 2048 for compatibility with earlier driver versions. The driver - really stores 1024 + tvnorm->vbipack * 4 samples per line in the - buffer. Note tvnorm->vbipack is <= 0xFF (limit of VBIPACK_LO + HI - is 0x1FF DWORDs) and VBI read()s store a frame counter in the last - four bytes of the VBI image. */ -#define VBI_BPL 2048 - -/* Compatibility. */ -#define VBI_DEFLINES 16 - -static unsigned int vbibufs = 4; -static unsigned int vbi_debug; - -module_param(vbibufs, int, 0444); -module_param(vbi_debug, int, 0644); -MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4"); -MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)"); - -#ifdef dprintk -# undef dprintk -#endif -#define dprintk(fmt, ...) \ -do { \ - if (vbi_debug) \ - pr_debug("%d: " fmt, btv->c.nr, ##__VA_ARGS__); \ -} while (0) - -#define IMAGE_SIZE(fmt) \ - (((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line) - -/* ----------------------------------------------------------------------- */ -/* vbi risc code + mm */ - -static int vbi_buffer_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) -{ - struct bttv_fh *fh = q->priv_data; - struct bttv *btv = fh->btv; - - if (0 == *count) - *count = vbibufs; - - *size = IMAGE_SIZE(&fh->vbi_fmt.fmt); - - dprintk("setup: samples=%u start=%d,%d count=%u,%u\n", - fh->vbi_fmt.fmt.samples_per_line, - fh->vbi_fmt.fmt.start[0], - fh->vbi_fmt.fmt.start[1], - fh->vbi_fmt.fmt.count[0], - fh->vbi_fmt.fmt.count[1]); - - return 0; -} - -static int vbi_buffer_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct bttv_fh *fh = q->priv_data; - struct bttv *btv = fh->btv; - struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); - const struct bttv_tvnorm *tvnorm; - unsigned int skip_lines0, skip_lines1, min_vdelay; - int redo_dma_risc; - int rc; - - buf->vb.size = IMAGE_SIZE(&fh->vbi_fmt.fmt); - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) - return -EINVAL; - - tvnorm = fh->vbi_fmt.tvnorm; - - /* There's no VBI_VDELAY register, RISC must skip the lines - we don't want. With default parameters we skip zero lines - as earlier driver versions did. The driver permits video - standard changes while capturing, so we use vbi_fmt.tvnorm - instead of btv->tvnorm to skip zero lines after video - standard changes as well. */ - - skip_lines0 = 0; - skip_lines1 = 0; - - if (fh->vbi_fmt.fmt.count[0] > 0) - skip_lines0 = max(0, (fh->vbi_fmt.fmt.start[0] - - tvnorm->vbistart[0])); - if (fh->vbi_fmt.fmt.count[1] > 0) - skip_lines1 = max(0, (fh->vbi_fmt.fmt.start[1] - - tvnorm->vbistart[1])); - - redo_dma_risc = 0; - - if (buf->vbi_skip[0] != skip_lines0 || - buf->vbi_skip[1] != skip_lines1 || - buf->vbi_count[0] != fh->vbi_fmt.fmt.count[0] || - buf->vbi_count[1] != fh->vbi_fmt.fmt.count[1]) { - buf->vbi_skip[0] = skip_lines0; - buf->vbi_skip[1] = skip_lines1; - buf->vbi_count[0] = fh->vbi_fmt.fmt.count[0]; - buf->vbi_count[1] = fh->vbi_fmt.fmt.count[1]; - redo_dma_risc = 1; - } - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - redo_dma_risc = 1; - if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) - goto fail; - } - - if (redo_dma_risc) { - unsigned int bpl, padding, offset; - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - - bpl = 2044; /* max. vbipack */ - padding = VBI_BPL - bpl; - - if (fh->vbi_fmt.fmt.count[0] > 0) { - rc = bttv_risc_packed(btv, &buf->top, - dma->sglist, - /* offset */ 0, bpl, - padding, skip_lines0, - fh->vbi_fmt.fmt.count[0]); - if (0 != rc) - goto fail; - } - - if (fh->vbi_fmt.fmt.count[1] > 0) { - offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL; - - rc = bttv_risc_packed(btv, &buf->bottom, - dma->sglist, - offset, bpl, - padding, skip_lines1, - fh->vbi_fmt.fmt.count[1]); - if (0 != rc) - goto fail; - } - } - - /* VBI capturing ends at VDELAY, start of video capturing, - no matter where the RISC program ends. VDELAY minimum is 2, - bounds.top is the corresponding first field line number - times two. VDELAY counts half field lines. */ - min_vdelay = MIN_VDELAY; - if (fh->vbi_fmt.end >= tvnorm->cropcap.bounds.top) - min_vdelay += fh->vbi_fmt.end - tvnorm->cropcap.bounds.top; - - /* For bttv_buffer_activate_vbi(). */ - buf->geo.vdelay = min_vdelay; - - buf->vb.state = VIDEOBUF_PREPARED; - buf->vb.field = field; - dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", - vb, &buf->top, &buf->bottom, - v4l2_field_names[buf->vb.field]); - return 0; - - fail: - bttv_dma_free(q,btv,buf); - return rc; -} - -static void -vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct bttv_fh *fh = q->priv_data; - struct bttv *btv = fh->btv; - struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); - - dprintk("queue %p\n",vb); - buf->vb.state = VIDEOBUF_QUEUED; - list_add_tail(&buf->vb.queue,&btv->vcapture); - if (NULL == btv->cvbi) { - fh->btv->loop_irq |= 4; - bttv_set_dma(btv,0x0c); - } -} - -static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct bttv_fh *fh = q->priv_data; - struct bttv *btv = fh->btv; - struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); - - dprintk("free %p\n",vb); - bttv_dma_free(q,fh->btv,buf); -} - -struct videobuf_queue_ops bttv_vbi_qops = { - .buf_setup = vbi_buffer_setup, - .buf_prepare = vbi_buffer_prepare, - .buf_queue = vbi_buffer_queue, - .buf_release = vbi_buffer_release, -}; - -/* ----------------------------------------------------------------------- */ - -static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm, - __s32 crop_start) -{ - __s32 min_start, max_start, max_end, f2_offset; - unsigned int i; - - /* For compatibility with earlier driver versions we must pretend - the VBI and video capture window may overlap. In reality RISC - magic aborts VBI capturing at the first line of video capturing, - leaving the rest of the buffer unchanged, usually all zero. - VBI capturing must always start before video capturing. >> 1 - because cropping counts field lines times two. */ - min_start = tvnorm->vbistart[0]; - max_start = (crop_start >> 1) - 1; - max_end = (tvnorm->cropcap.bounds.top - + tvnorm->cropcap.bounds.height) >> 1; - - if (min_start > max_start) - return -EBUSY; - - BUG_ON(max_start >= max_end); - - f->sampling_rate = tvnorm->Fsc; - f->samples_per_line = VBI_BPL; - f->sample_format = V4L2_PIX_FMT_GREY; - f->offset = VBI_OFFSET; - - f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0]; - - for (i = 0; i < 2; ++i) { - if (0 == f->count[i]) { - /* No data from this field. We leave f->start[i] - alone because VIDIOCSVBIFMT is w/o and EINVALs - when a driver does not support exactly the - requested parameters. */ - } else { - s64 start, count; - - start = clamp(f->start[i], min_start, max_start); - /* s64 to prevent overflow. */ - count = (s64) f->start[i] + f->count[i] - start; - f->start[i] = start; - f->count[i] = clamp(count, (s64) 1, - max_end - start); - } - - min_start += f2_offset; - max_start += f2_offset; - max_end += f2_offset; - } - - if (0 == (f->count[0] | f->count[1])) { - /* As in earlier driver versions. */ - f->start[0] = tvnorm->vbistart[0]; - f->start[1] = tvnorm->vbistart[1]; - f->count[0] = 1; - f->count[1] = 1; - } - - f->flags = 0; - - f->reserved[0] = 0; - f->reserved[1] = 0; - - return 0; -} - -int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - const struct bttv_tvnorm *tvnorm; - __s32 crop_start; - - mutex_lock(&btv->lock); - - tvnorm = &bttv_tvnorms[btv->tvnorm]; - crop_start = btv->crop_start; - - mutex_unlock(&btv->lock); - - return try_fmt(&frt->fmt.vbi, tvnorm, crop_start); -} - - -int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - const struct bttv_tvnorm *tvnorm; - __s32 start1, end; - int rc; - - mutex_lock(&btv->lock); - - rc = -EBUSY; - if (fh->resources & RESOURCE_VBI) - goto fail; - - tvnorm = &bttv_tvnorms[btv->tvnorm]; - - rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start); - if (0 != rc) - goto fail; - - start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] + - tvnorm->vbistart[0]; - - /* First possible line of video capturing. Should be - max(f->start[0] + f->count[0], start1 + f->count[1]) * 2 - when capturing both fields. But for compatibility we must - pretend the VBI and video capture window may overlap, - so end = start + 1, the lowest possible value, times two - because vbi_fmt.end counts field lines times two. */ - end = max(frt->fmt.vbi.start[0], start1) * 2 + 2; - - mutex_lock(&fh->vbi.vb_lock); - - fh->vbi_fmt.fmt = frt->fmt.vbi; - fh->vbi_fmt.tvnorm = tvnorm; - fh->vbi_fmt.end = end; - - mutex_unlock(&fh->vbi.vb_lock); - - rc = 0; - - fail: - mutex_unlock(&btv->lock); - - return rc; -} - - -int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt) -{ - struct bttv_fh *fh = f; - const struct bttv_tvnorm *tvnorm; - - frt->fmt.vbi = fh->vbi_fmt.fmt; - - tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; - - if (tvnorm != fh->vbi_fmt.tvnorm) { - __s32 max_end; - unsigned int i; - - /* As in vbi_buffer_prepare() this imitates the - behaviour of earlier driver versions after video - standard changes, with default parameters anyway. */ - - max_end = (tvnorm->cropcap.bounds.top - + tvnorm->cropcap.bounds.height) >> 1; - - frt->fmt.vbi.sampling_rate = tvnorm->Fsc; - - for (i = 0; i < 2; ++i) { - __s32 new_start; - - new_start = frt->fmt.vbi.start[i] - + tvnorm->vbistart[i] - - fh->vbi_fmt.tvnorm->vbistart[i]; - - frt->fmt.vbi.start[i] = min(new_start, max_end - 1); - frt->fmt.vbi.count[i] = - min((__s32) frt->fmt.vbi.count[i], - max_end - frt->fmt.vbi.start[i]); - - max_end += tvnorm->vbistart[1] - - tvnorm->vbistart[0]; - } - } - return 0; -} - -void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm) -{ - const struct bttv_tvnorm *tvnorm; - unsigned int real_samples_per_line; - unsigned int real_count; - - tvnorm = &bttv_tvnorms[norm]; - - f->fmt.sampling_rate = tvnorm->Fsc; - f->fmt.samples_per_line = VBI_BPL; - f->fmt.sample_format = V4L2_PIX_FMT_GREY; - f->fmt.offset = VBI_OFFSET; - f->fmt.start[0] = tvnorm->vbistart[0]; - f->fmt.start[1] = tvnorm->vbistart[1]; - f->fmt.count[0] = VBI_DEFLINES; - f->fmt.count[1] = VBI_DEFLINES; - f->fmt.flags = 0; - f->fmt.reserved[0] = 0; - f->fmt.reserved[1] = 0; - - /* For compatibility the buffer size must be 2 * VBI_DEFLINES * - VBI_BPL regardless of the current video standard. */ - real_samples_per_line = 1024 + tvnorm->vbipack * 4; - real_count = ((tvnorm->cropcap.defrect.top >> 1) - - tvnorm->vbistart[0]); - - BUG_ON(real_samples_per_line > VBI_BPL); - BUG_ON(real_count > VBI_DEFLINES); - - f->tvnorm = tvnorm; - - /* See bttv_vbi_fmt_set(). */ - f->end = tvnorm->vbistart[0] * 2 + 2; -} - -/* ----------------------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h deleted file mode 100644 index 79a11240a590..000000000000 --- a/drivers/media/video/bt8xx/bttv.h +++ /dev/null @@ -1,376 +0,0 @@ -/* - * - * bttv - Bt848 frame grabber driver - * - * card ID's and external interfaces of the bttv driver - * basically stuff needed by other drivers (i2c, lirc, ...) - * and is supported not to change much over time. - * - * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de) - * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> - * - */ - -#ifndef _BTTV_H_ -#define _BTTV_H_ - -#include <linux/videodev2.h> -#include <linux/i2c.h> -#include <media/v4l2-device.h> -#include <media/i2c-addr.h> -#include <media/tuner.h> - -/* ---------------------------------------------------------- */ -/* exported by bttv-cards.c */ - -#define BTTV_BOARD_UNKNOWN 0x00 -#define BTTV_BOARD_MIRO 0x01 -#define BTTV_BOARD_HAUPPAUGE 0x02 -#define BTTV_BOARD_STB 0x03 -#define BTTV_BOARD_INTEL 0x04 -#define BTTV_BOARD_DIAMOND 0x05 -#define BTTV_BOARD_AVERMEDIA 0x06 -#define BTTV_BOARD_MATRIX_VISION 0x07 -#define BTTV_BOARD_FLYVIDEO 0x08 -#define BTTV_BOARD_TURBOTV 0x09 -#define BTTV_BOARD_HAUPPAUGE878 0x0a -#define BTTV_BOARD_MIROPRO 0x0b -#define BTTV_BOARD_ADSTECH_TV 0x0c -#define BTTV_BOARD_AVERMEDIA98 0x0d -#define BTTV_BOARD_VHX 0x0e -#define BTTV_BOARD_ZOLTRIX 0x0f -#define BTTV_BOARD_PIXVIEWPLAYTV 0x10 -#define BTTV_BOARD_WINVIEW_601 0x11 -#define BTTV_BOARD_AVEC_INTERCAP 0x12 -#define BTTV_BOARD_LIFE_FLYKIT 0x13 -#define BTTV_BOARD_CEI_RAFFLES 0x14 -#define BTTV_BOARD_CONFERENCETV 0x15 -#define BTTV_BOARD_PHOEBE_TVMAS 0x16 -#define BTTV_BOARD_MODTEC_205 0x17 -#define BTTV_BOARD_MAGICTVIEW061 0x18 -#define BTTV_BOARD_VOBIS_BOOSTAR 0x19 -#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a -#define BTTV_BOARD_MAXI 0x1b -#define BTTV_BOARD_TERRATV 0x1c -#define BTTV_BOARD_PXC200 0x1d -#define BTTV_BOARD_FLYVIDEO_98 0x1e -#define BTTV_BOARD_IPROTV 0x1f -#define BTTV_BOARD_INTEL_C_S_PCI 0x20 -#define BTTV_BOARD_TERRATVALUE 0x21 -#define BTTV_BOARD_WINFAST2000 0x22 -#define BTTV_BOARD_CHRONOS_VS2 0x23 -#define BTTV_BOARD_TYPHOON_TVIEW 0x24 -#define BTTV_BOARD_PXELVWPLTVPRO 0x25 -#define BTTV_BOARD_MAGICTVIEW063 0x26 -#define BTTV_BOARD_PINNACLE 0x27 -#define BTTV_BOARD_STB2 0x28 -#define BTTV_BOARD_AVPHONE98 0x29 -#define BTTV_BOARD_PV951 0x2a -#define BTTV_BOARD_ONAIR_TV 0x2b -#define BTTV_BOARD_SIGMA_TVII_FM 0x2c -#define BTTV_BOARD_MATRIX_VISION2 0x2d -#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e -#define BTTV_BOARD_TERRATVRADIO 0x2f -#define BTTV_BOARD_DYNALINK 0x30 -#define BTTV_BOARD_GVBCTV3PCI 0x31 -#define BTTV_BOARD_PXELVWPLTVPAK 0x32 -#define BTTV_BOARD_EAGLE 0x33 -#define BTTV_BOARD_PINNACLEPRO 0x34 -#define BTTV_BOARD_TVIEW_RDS_FM 0x35 -#define BTTV_BOARD_LIFETEC_9415 0x36 -#define BTTV_BOARD_BESTBUY_EASYTV 0x37 -#define BTTV_BOARD_FLYVIDEO_98FM 0x38 -#define BTTV_BOARD_GRANDTEC 0x39 -#define BTTV_BOARD_ASKEY_CPH060 0x3a -#define BTTV_BOARD_ASKEY_CPH03X 0x3b -#define BTTV_BOARD_MM100PCTV 0x3c -#define BTTV_BOARD_GMV1 0x3d -#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e -#define BTTV_BOARD_ATI_TVWONDER 0x3f -#define BTTV_BOARD_ATI_TVWONDERVE 0x40 -#define BTTV_BOARD_FLYVIDEO2000 0x41 -#define BTTV_BOARD_TERRATVALUER 0x42 -#define BTTV_BOARD_GVBCTV4PCI 0x43 -#define BTTV_BOARD_VOODOOTV_FM 0x44 -#define BTTV_BOARD_AIMMS 0x45 -#define BTTV_BOARD_PV_BT878P_PLUS 0x46 -#define BTTV_BOARD_FLYVIDEO98EZ 0x47 -#define BTTV_BOARD_PV_BT878P_9B 0x48 -#define BTTV_BOARD_SENSORAY311_611 0x49 -#define BTTV_BOARD_RV605 0x4a -#define BTTV_BOARD_POWERCLR_MTV878 0x4b -#define BTTV_BOARD_WINDVR 0x4c -#define BTTV_BOARD_GRANDTEC_MULTI 0x4d -#define BTTV_BOARD_KWORLD 0x4e -#define BTTV_BOARD_DSP_TCVIDEO 0x4f -#define BTTV_BOARD_HAUPPAUGEPVR 0x50 -#define BTTV_BOARD_GVBCTV5PCI 0x51 -#define BTTV_BOARD_OSPREY1x0 0x52 -#define BTTV_BOARD_OSPREY1x0_848 0x53 -#define BTTV_BOARD_OSPREY101_848 0x54 -#define BTTV_BOARD_OSPREY1x1 0x55 -#define BTTV_BOARD_OSPREY1x1_SVID 0x56 -#define BTTV_BOARD_OSPREY2xx 0x57 -#define BTTV_BOARD_OSPREY2x0_SVID 0x58 -#define BTTV_BOARD_OSPREY2x0 0x59 -#define BTTV_BOARD_OSPREY500 0x5a -#define BTTV_BOARD_OSPREY540 0x5b -#define BTTV_BOARD_OSPREY2000 0x5c -#define BTTV_BOARD_IDS_EAGLE 0x5d -#define BTTV_BOARD_PINNACLESAT 0x5e -#define BTTV_BOARD_FORMAC_PROTV 0x5f -#define BTTV_BOARD_MACHTV 0x60 -#define BTTV_BOARD_EURESYS_PICOLO 0x61 -#define BTTV_BOARD_PV150 0x62 -#define BTTV_BOARD_AD_TVK503 0x63 -#define BTTV_BOARD_HERCULES_SM_TV 0x64 -#define BTTV_BOARD_PACETV 0x65 -#define BTTV_BOARD_IVC200 0x66 -#define BTTV_BOARD_XGUARD 0x67 -#define BTTV_BOARD_NEBULA_DIGITV 0x68 -#define BTTV_BOARD_PV143 0x69 -#define BTTV_BOARD_VD009X1_VD011_MINIDIN 0x6a -#define BTTV_BOARD_VD009X1_VD011_COMBI 0x6b -#define BTTV_BOARD_VD009_MINIDIN 0x6c -#define BTTV_BOARD_VD009_COMBI 0x6d -#define BTTV_BOARD_IVC100 0x6e -#define BTTV_BOARD_IVC120 0x6f -#define BTTV_BOARD_PC_HDTV 0x70 -#define BTTV_BOARD_TWINHAN_DST 0x71 -#define BTTV_BOARD_WINFASTVC100 0x72 -#define BTTV_BOARD_TEV560 0x73 -#define BTTV_BOARD_SIMUS_GVC1100 0x74 -#define BTTV_BOARD_NGSTV_PLUS 0x75 -#define BTTV_BOARD_LMLBT4 0x76 -#define BTTV_BOARD_TEKRAM_M205 0x77 -#define BTTV_BOARD_CONTVFMI 0x78 -#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 -#define BTTV_BOARD_SPIRIT_TV 0x7a -#define BTTV_BOARD_AVDVBT_771 0x7b -#define BTTV_BOARD_AVDVBT_761 0x7c -#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d -#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e -#define BTTV_BOARD_APAC_VIEWCOMP 0x7f -#define BTTV_BOARD_DVICO_DVBT_LITE 0x80 -#define BTTV_BOARD_VGEAR_MYVCD 0x81 -#define BTTV_BOARD_SUPER_TV 0x82 -#define BTTV_BOARD_TIBET_CS16 0x83 -#define BTTV_BOARD_KODICOM_4400R 0x84 -#define BTTV_BOARD_KODICOM_4400R_SL 0x85 -#define BTTV_BOARD_ADLINK_RTV24 0x86 -#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 -#define BTTV_BOARD_ACORP_Y878F 0x88 -#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89 -#define BTTV_BOARD_PV_BT878P_2E 0x8a -#define BTTV_BOARD_PV_M4900 0x8b -#define BTTV_BOARD_OSPREY440 0x8c -#define BTTV_BOARD_ASOUND_SKYEYE 0x8d -#define BTTV_BOARD_SABRENT_TVFM 0x8e -#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f -#define BTTV_BOARD_MACHTV_MAGICTV 0x90 -#define BTTV_BOARD_SSAI_SECURITY 0x91 -#define BTTV_BOARD_SSAI_ULTRASOUND 0x92 -#define BTTV_BOARD_VOODOOTV_200 0x93 -#define BTTV_BOARD_DVICO_FUSIONHDTV_2 0x94 -#define BTTV_BOARD_TYPHOON_TVTUNERPCI 0x95 -#define BTTV_BOARD_GEOVISION_GV600 0x96 -#define BTTV_BOARD_KOZUMI_KTV_01C 0x97 -#define BTTV_BOARD_ENLTV_FM_2 0x98 -#define BTTV_BOARD_VD012 0x99 -#define BTTV_BOARD_VD012_X1 0x9a -#define BTTV_BOARD_VD012_X2 0x9b -#define BTTV_BOARD_IVCE8784 0x9c -#define BTTV_BOARD_GEOVISION_GV800S 0x9d -#define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e -#define BTTV_BOARD_PV183 0x9f -#define BTTV_BOARD_TVT_TD3116 0xa0 -#define BTTV_BOARD_APOSONIC_WDVR 0xa1 - -/* more card-specific defines */ -#define PT2254_L_CHANNEL 0x10 -#define PT2254_R_CHANNEL 0x08 -#define PT2254_DBS_IN_2 0x400 -#define PT2254_DBS_IN_10 0x20000 -#define WINVIEW_PT2254_CLK 0x40 -#define WINVIEW_PT2254_DATA 0x20 -#define WINVIEW_PT2254_STROBE 0x80 - -struct bttv_core { - /* device structs */ - struct v4l2_device v4l2_dev; - struct pci_dev *pci; - struct i2c_adapter i2c_adap; - struct list_head subs; /* struct bttv_sub_device */ - - /* device config */ - unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ - unsigned int type; /* card type (pointer into tvcards[]) */ -}; - -struct bttv; - -struct tvcard { - char *name; - void (*volume_gpio)(struct bttv *btv, __u16 volume); - void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set); - void (*muxsel_hook)(struct bttv *btv, unsigned int input); - - /* MUX bits for each input, two bits per input starting with the LSB */ - u32 muxsel; /* Use MUXSEL() to set */ - - u32 gpiomask; - u32 gpiomux[4]; /* Tuner, Radio, external, internal */ - u32 gpiomute; /* GPIO mute setting */ - u32 gpiomask2; /* GPIO MUX mask */ - - unsigned int tuner_type; - u8 tuner_addr; - u8 video_inputs; /* Number of inputs */ - unsigned int svhs:4; /* Which input is s-video */ -#define NO_SVHS 15 - unsigned int pll:2; -#define PLL_NONE 0 -#define PLL_28 1 -#define PLL_35 2 - - /* i2c audio flags */ - unsigned int no_msp34xx:1; - unsigned int no_tda7432:1; - unsigned int msp34xx_alt:1; - /* Note: currently no card definition needs to mark the presence - of a RDS saa6588 chip. If this is ever needed, then add a new - 'has_saa6588' bit here. */ - - unsigned int no_video:1; /* video pci function is unused */ - unsigned int has_dvb:1; - unsigned int has_remote:1; - unsigned int has_radio:1; - unsigned int has_dig_in:1; /* Has digital input (always last input) */ - unsigned int no_gpioirq:1; -}; - -extern struct tvcard bttv_tvcards[]; - -/* - * This bit of cpp voodoo is used to create a macro with a variable number of - * arguments (1 to 16). It will pack each argument into a word two bits at a - * time. It can't be a function because it needs to be compile time constant to - * initialize structures. Since each argument must fit in two bits, it's ok - * that they are changed to octal. One should not use hex number, macros, or - * anything else with this macro. Just use plain integers from 0 to 3. - */ -#define _MUXSELf(a) 0##a << 30 -#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b) -#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b) -#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b) -#define _MUXSELb(a, b...) 0##a << 22 | _MUXSELc(b) -#define _MUXSELa(a, b...) 0##a << 20 | _MUXSELb(b) -#define _MUXSEL9(a, b...) 0##a << 18 | _MUXSELa(b) -#define _MUXSEL8(a, b...) 0##a << 16 | _MUXSEL9(b) -#define _MUXSEL7(a, b...) 0##a << 14 | _MUXSEL8(b) -#define _MUXSEL6(a, b...) 0##a << 12 | _MUXSEL7(b) -#define _MUXSEL5(a, b...) 0##a << 10 | _MUXSEL6(b) -#define _MUXSEL4(a, b...) 0##a << 8 | _MUXSEL5(b) -#define _MUXSEL3(a, b...) 0##a << 6 | _MUXSEL4(b) -#define _MUXSEL2(a, b...) 0##a << 4 | _MUXSEL3(b) -#define _MUXSEL1(a, b...) 0##a << 2 | _MUXSEL2(b) -#define MUXSEL(a, b...) (a | _MUXSEL1(b)) - -/* identification / initialization of the card */ -extern void bttv_idcard(struct bttv *btv); -extern void bttv_init_card1(struct bttv *btv); -extern void bttv_init_card2(struct bttv *btv); -extern void bttv_init_tuner(struct bttv *btv); - -/* card-specific funtions */ -extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); -extern u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits); - -/* extra tweaks for some chipsets */ -extern void bttv_check_chipset(void); -extern int bttv_handle_chipset(struct bttv *btv); - -/* ---------------------------------------------------------- */ -/* exported by bttv-if.c */ - -/* this obsolete -- please use the sysfs-based - interface below for new code */ - -extern struct pci_dev* bttv_get_pcidev(unsigned int card); - -/* sets GPOE register (BT848_GPIO_OUT_EN) to new value: - data | (current_GPOE_value & ~mask) - returns negative value if error occurred -*/ -extern int bttv_gpio_enable(unsigned int card, - unsigned long mask, unsigned long data); - -/* fills data with GPDATA register contents - returns negative value if error occurred -*/ -extern int bttv_read_gpio(unsigned int card, unsigned long *data); - -/* sets GPDATA register to new value: - (data & mask) | (current_GPDATA_value & ~mask) - returns negative value if error occurred -*/ -extern int bttv_write_gpio(unsigned int card, - unsigned long mask, unsigned long data); - - - - -/* ---------------------------------------------------------- */ -/* sysfs/driver-moded based gpio access interface */ - -struct bttv_sub_device { - struct device dev; - struct bttv_core *core; - struct list_head list; -}; -#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev) - -struct bttv_sub_driver { - struct device_driver drv; - char wanted[20]; - int (*probe)(struct bttv_sub_device *sub); - void (*remove)(struct bttv_sub_device *sub); -}; -#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) - -int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted); -int bttv_sub_unregister(struct bttv_sub_driver *drv); - -/* gpio access functions */ -void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits); -u32 bttv_gpio_read(struct bttv_core *core); -void bttv_gpio_write(struct bttv_core *core, u32 value); -void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); - -#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits) -#define gpio_read() bttv_gpio_read(&btv->c) -#define gpio_write(value) bttv_gpio_write(&btv->c, value) -#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits) - - -/* ---------------------------------------------------------- */ -/* i2c */ - -#define bttv_call_all(btv, o, f, args...) \ - v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args) - -extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for); -extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, - unsigned char b2, int both); -extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); - -extern int bttv_input_init(struct bttv *dev); -extern void bttv_input_fini(struct bttv *dev); -extern void bttv_input_irq(struct bttv *dev); - -#endif /* _BTTV_H_ */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h deleted file mode 100644 index 70fd4f23f605..000000000000 --- a/drivers/media/video/bt8xx/bttvp.h +++ /dev/null @@ -1,535 +0,0 @@ -/* - - bttv - Bt848 frame grabber driver - - bttv's *private* header file -- nobody other than bttv itself - should ever include this file. - - (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org> - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _BTTVP_H_ -#define _BTTVP_H_ - -#include <linux/types.h> -#include <linux/wait.h> -#include <linux/i2c.h> -#include <linux/i2c-algo-bit.h> -#include <linux/pci.h> -#include <linux/input.h> -#include <linux/mutex.h> -#include <linux/scatterlist.h> -#include <asm/io.h> -#include <media/v4l2-common.h> -#include <linux/device.h> -#include <media/videobuf-dma-sg.h> -#include <media/tveeprom.h> -#include <media/rc-core.h> -#include <media/ir-kbd-i2c.h> - -#include "bt848.h" -#include "bttv.h" -#include "btcx-risc.h" - -#ifdef __KERNEL__ - -#define FORMAT_FLAGS_DITHER 0x01 -#define FORMAT_FLAGS_PACKED 0x02 -#define FORMAT_FLAGS_PLANAR 0x04 -#define FORMAT_FLAGS_RAW 0x08 -#define FORMAT_FLAGS_CrCb 0x10 - -#define RISC_SLOT_O_VBI 4 -#define RISC_SLOT_O_FIELD 6 -#define RISC_SLOT_E_VBI 10 -#define RISC_SLOT_E_FIELD 12 -#define RISC_SLOT_LOOP 14 - -#define RESOURCE_OVERLAY 1 -#define RESOURCE_VIDEO_STREAM 2 -#define RESOURCE_VBI 4 -#define RESOURCE_VIDEO_READ 8 - -#define RAW_LINES 640 -#define RAW_BPL 1024 - -#define UNSET (-1U) - -/* Min. value in VDELAY register. */ -#define MIN_VDELAY 2 -/* Even to get Cb first, odd for Cr. */ -#define MAX_HDELAY (0x3FF & -2) -/* Limits scaled width, which must be a multiple of 4. */ -#define MAX_HACTIVE (0x3FF & -4) - -#define BTTV_NORMS (\ - V4L2_STD_PAL | V4L2_STD_PAL_N | \ - V4L2_STD_PAL_Nc | V4L2_STD_SECAM | \ - V4L2_STD_NTSC | V4L2_STD_PAL_M | \ - V4L2_STD_PAL_60) -/* ---------------------------------------------------------- */ - -struct bttv_tvnorm { - int v4l2_id; - char *name; - u32 Fsc; - u16 swidth, sheight; /* scaled standard width, height */ - u16 totalwidth; - u8 adelay, bdelay, iform; - u32 scaledtwidth; - u16 hdelayx1, hactivex1; - u16 vdelay; - u8 vbipack; - u16 vtotal; - int sram; - /* ITU-R frame line number of the first VBI line we can - capture, of the first and second field. The last possible line - is determined by cropcap.bounds. */ - u16 vbistart[2]; - /* Horizontally this counts fCLKx1 samples following the leading - edge of the horizontal sync pulse, vertically ITU-R frame line - numbers of the first field times two (2, 4, 6, ... 524 or 624). */ - struct v4l2_cropcap cropcap; -}; -extern const struct bttv_tvnorm bttv_tvnorms[]; - -struct bttv_format { - char *name; - int fourcc; /* video4linux 2 */ - int btformat; /* BT848_COLOR_FMT_* */ - int btswap; /* BT848_COLOR_CTL_* */ - int depth; /* bit/pixel */ - int flags; - int hshift,vshift; /* for planar modes */ -}; - -struct bttv_ir { - struct rc_dev *dev; - struct timer_list timer; - - char name[32]; - char phys[32]; - - /* Usual gpio signalling */ - u32 mask_keycode; - u32 mask_keydown; - u32 mask_keyup; - u32 polling; - u32 last_gpio; - int shift_by; - int start; // What should RC5_START() be - int addr; // What RC5_ADDR() should be. - int rc5_remote_gap; - - /* RC5 gpio */ - bool rc5_gpio; /* Is RC5 legacy GPIO enabled? */ - u32 last_bit; /* last raw bit seen */ - u32 code; /* raw code under construction */ - struct timeval base_time; /* time of last seen code */ - bool active; /* building raw code */ -}; - - -/* ---------------------------------------------------------- */ - -struct bttv_geometry { - u8 vtc,crop,comb; - u16 width,hscale,hdelay; - u16 sheight,vscale,vdelay,vtotal; -}; - -struct bttv_buffer { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - /* bttv specific */ - const struct bttv_format *fmt; - unsigned int tvnorm; - int btformat; - int btswap; - struct bttv_geometry geo; - struct btcx_riscmem top; - struct btcx_riscmem bottom; - struct v4l2_rect crop; - unsigned int vbi_skip[2]; - unsigned int vbi_count[2]; -}; - -struct bttv_buffer_set { - struct bttv_buffer *top; /* top field buffer */ - struct bttv_buffer *bottom; /* bottom field buffer */ - unsigned int top_irq; - unsigned int frame_irq; -}; - -struct bttv_overlay { - unsigned int tvnorm; - struct v4l2_rect w; - enum v4l2_field field; - struct v4l2_clip *clips; - int nclips; - int setup_ok; -}; - -struct bttv_vbi_fmt { - struct v4l2_vbi_format fmt; - - /* fmt.start[] and count[] refer to this video standard. */ - const struct bttv_tvnorm *tvnorm; - - /* Earliest possible start of video capturing with this - v4l2_vbi_format, in struct bttv_crop.rect units. */ - __s32 end; -}; - -/* bttv-vbi.c */ -void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm); - -struct bttv_crop { - /* A cropping rectangle in struct bttv_tvnorm.cropcap units. */ - struct v4l2_rect rect; - - /* Scaled image size limits with this crop rect. Divide - max_height, but not min_height, by two when capturing - single fields. See also bttv_crop_reset() and - bttv_crop_adjust() in bttv-driver.c. */ - __s32 min_scaled_width; - __s32 min_scaled_height; - __s32 max_scaled_width; - __s32 max_scaled_height; -}; - -struct bttv_fh { - struct bttv *btv; - int resources; -#ifdef VIDIOC_G_PRIORITY - enum v4l2_priority prio; -#endif - enum v4l2_buf_type type; - - /* video capture */ - struct videobuf_queue cap; - const struct bttv_format *fmt; - int width; - int height; - - /* video overlay */ - const struct bttv_format *ovfmt; - struct bttv_overlay ov; - - /* Application called VIDIOC_S_CROP. */ - int do_crop; - - /* vbi capture */ - struct videobuf_queue vbi; - /* Current VBI capture window as seen through this fh (cannot - be global for compatibility with earlier drivers). Protected - by struct bttv.lock and struct bttv_fh.vbi.lock. */ - struct bttv_vbi_fmt vbi_fmt; -}; - -/* ---------------------------------------------------------- */ -/* bttv-risc.c */ - -/* risc code generators - capture */ -int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, - struct scatterlist *sglist, - unsigned int offset, unsigned int bpl, - unsigned int pitch, unsigned int skip_lines, - unsigned int store_lines); - -/* control dma register + risc main loop */ -void bttv_set_dma(struct bttv *btv, int override); -int bttv_risc_init_main(struct bttv *btv); -int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, - int irqflags); - -/* capture buffer handling */ -int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf); -int bttv_buffer_activate_video(struct bttv *btv, - struct bttv_buffer_set *set); -int bttv_buffer_activate_vbi(struct bttv *btv, - struct bttv_buffer *vbi); -void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv, - struct bttv_buffer *buf); - -/* overlay handling */ -int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, - const struct bttv_format *fmt, - struct bttv_buffer *buf); - - -/* ---------------------------------------------------------- */ -/* bttv-vbi.c */ - -int bttv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); -int bttv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); -int bttv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); - -extern struct videobuf_queue_ops bttv_vbi_qops; - -/* ---------------------------------------------------------- */ -/* bttv-gpio.c */ - -extern struct bus_type bttv_sub_bus_type; -int bttv_sub_add_device(struct bttv_core *core, char *name); -int bttv_sub_del_devices(struct bttv_core *core); - -/* ---------------------------------------------------------- */ -/* bttv-cards.c */ - -extern int no_overlay; - -/* ---------------------------------------------------------- */ -/* bttv-input.c */ - -extern void init_bttv_i2c_ir(struct bttv *btv); -extern int fini_bttv_i2c(struct bttv *btv); - -/* ---------------------------------------------------------- */ -/* bttv-driver.c */ - -/* insmod options */ -extern unsigned int bttv_verbose; -extern unsigned int bttv_debug; -extern unsigned int bttv_gpio; -extern void bttv_gpio_tracking(struct bttv *btv, char *comment); -extern int init_bttv_i2c(struct bttv *btv); - -#define dprintk(fmt, ...) \ -do { \ - if (bttv_debug >= 1) \ - pr_debug(fmt, ##__VA_ARGS__); \ -} while (0) -#define dprintk_cont(fmt, ...) \ -do { \ - if (bttv_debug >= 1) \ - pr_cont(fmt, ##__VA_ARGS__); \ -} while (0) -#define d2printk(fmt, ...) \ -do { \ - if (bttv_debug >= 2) \ - printk(fmt, ##__VA_ARGS__); \ -} while (0) - -#define BTTV_MAX_FBUF 0x208000 -#define BTTV_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ -#define BTTV_FREE_IDLE msecs_to_jiffies(1000) /* one second */ - - -struct bttv_pll_info { - unsigned int pll_ifreq; /* PLL input frequency */ - unsigned int pll_ofreq; /* PLL output frequency */ - unsigned int pll_crystal; /* Crystal used for input */ - unsigned int pll_current; /* Currently programmed ofreq */ -}; - -/* for gpio-connected remote control */ -struct bttv_input { - struct input_dev *dev; - char name[32]; - char phys[32]; - u32 mask_keycode; - u32 mask_keydown; -}; - -struct bttv_suspend_state { - u32 gpio_enable; - u32 gpio_data; - int disabled; - int loop_irq; - struct bttv_buffer_set video; - struct bttv_buffer *vbi; -}; - -struct bttv { - struct bttv_core c; - - /* pci device config */ - unsigned short id; - unsigned char revision; - unsigned char __iomem *bt848_mmio; /* pointer to mmio */ - - /* card configuration info */ - unsigned int cardid; /* pci subsystem id (bt878 based ones) */ - unsigned int tuner_type; /* tuner chip type */ - unsigned int tda9887_conf; - unsigned int svhs, dig; - unsigned int has_saa6588:1; - struct bttv_pll_info pll; - int triton1; - int gpioirq; - - int use_i2c_hw; - - /* old gpio interface */ - int shutdown; - - void (*volume_gpio)(struct bttv *btv, __u16 volume); - void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set); - - /* new gpio interface */ - spinlock_t gpio_lock; - - /* i2c layer */ - struct i2c_algo_bit_data i2c_algo; - struct i2c_client i2c_client; - int i2c_state, i2c_rc; - int i2c_done; - wait_queue_head_t i2c_queue; - struct v4l2_subdev *sd_msp34xx; - struct v4l2_subdev *sd_tvaudio; - - /* video4linux (1) */ - struct video_device *video_dev; - struct video_device *radio_dev; - struct video_device *vbi_dev; - - /* infrared remote */ - int has_remote; - struct bttv_ir *remote; - - /* I2C remote data */ - struct IR_i2c_init_data init_data; - - /* locking */ - spinlock_t s_lock; - struct mutex lock; - int resources; -#ifdef VIDIOC_G_PRIORITY - struct v4l2_prio_state prio; -#endif - - /* video state */ - unsigned int input; - unsigned int audio; - unsigned int mute; - unsigned long freq; - unsigned int tvnorm; - int hue, contrast, bright, saturation; - struct v4l2_framebuffer fbuf; - unsigned int field_count; - - /* various options */ - int opt_combfilter; - int opt_lumafilter; - int opt_automute; - int opt_chroma_agc; - int opt_adc_crush; - int opt_vcr_hack; - int opt_whitecrush_upper; - int opt_whitecrush_lower; - int opt_uv_ratio; - int opt_full_luma_range; - int opt_coring; - - /* radio data/state */ - int has_radio; - int radio_user; - int radio_uses_msp_demodulator; - - /* miro/pinnacle + Aimslab VHX - philips matchbox (tea5757 radio tuner) support */ - int has_matchbox; - int mbox_we; - int mbox_data; - int mbox_clk; - int mbox_most; - int mbox_mask; - - /* ISA stuff (Terratec Active Radio Upgrade) */ - int mbox_ior; - int mbox_iow; - int mbox_csel; - - /* risc memory management data - - must acquire s_lock before changing these - - only the irq handler is supported to touch top + bottom + vcurr */ - struct btcx_riscmem main; - struct bttv_buffer *screen; /* overlay */ - struct list_head capture; /* video capture queue */ - struct list_head vcapture; /* vbi capture queue */ - struct bttv_buffer_set curr; /* active buffers */ - struct bttv_buffer *cvbi; /* active vbi buffer */ - int loop_irq; - int new_input; - - unsigned long cap_ctl; - unsigned long dma_on; - struct timer_list timeout; - struct bttv_suspend_state state; - - /* stats */ - unsigned int errors; - unsigned int framedrop; - unsigned int irq_total; - unsigned int irq_me; - - unsigned int users; - struct bttv_fh init; - - /* used to make dvb-bt8xx autoloadable */ - struct work_struct request_module_wk; - - /* Default (0) and current (1) video capturing and overlay - cropping parameters in bttv_tvnorm.cropcap units. Protected - by bttv.lock. */ - struct bttv_crop crop[2]; - - /* Earliest possible start of video capturing in - bttv_tvnorm.cropcap line units. Set by check_alloc_btres() - and free_btres(). Protected by bttv.lock. */ - __s32 vbi_end; - - /* Latest possible end of VBI capturing (= crop[x].rect.top when - VIDEO_RESOURCES are locked). Set by check_alloc_btres() - and free_btres(). Protected by bttv.lock. */ - __s32 crop_start; -}; - -static inline struct bttv *to_bttv(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct bttv, c.v4l2_dev); -} - -/* our devices */ -#define BTTV_MAX 32 -extern unsigned int bttv_num; -extern struct bttv *bttvs[BTTV_MAX]; - -static inline unsigned int bttv_muxsel(const struct bttv *btv, - unsigned int input) -{ - return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3; -} - -#endif - -#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr)) -#define btread(adr) readl(btv->bt848_mmio+(adr)) - -#define btand(dat,adr) btwrite((dat) & btread(adr), adr) -#define btor(dat,adr) btwrite((dat) | btread(adr), adr) -#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) - -#endif /* _BTTVP_H_ */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ |