diff options
Diffstat (limited to 'drivers/media/video/cx23885')
| -rw-r--r-- | drivers/media/video/cx23885/Kconfig | 30 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/Makefile | 10 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-417.c | 1821 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-cards.c | 664 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-core.c | 1841 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-dvb.c | 627 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-i2c.c | 456 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-reg.h | 444 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-vbi.c | 248 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-video.c | 1557 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885.h | 486 |
11 files changed, 0 insertions, 8184 deletions
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig deleted file mode 100644 index 00f1e2e8889..00000000000 --- a/drivers/media/video/cx23885/Kconfig +++ /dev/null @@ -1,30 +0,0 @@ -config VIDEO_CX23885 - tristate "Conexant cx23885 (2388x successor) support" - depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT - select I2C_ALGOBIT - select VIDEO_BTCX - select VIDEO_TUNER - select VIDEO_TVEEPROM - select VIDEO_IR - select VIDEOBUF_DVB - select VIDEOBUF_DMA_SG - select VIDEO_CX25840 - select VIDEO_CX2341X - select DVB_DIB7000P if !DVB_FE_CUSTOMISE - select DVB_S5H1409 if !DVB_FE_CUSTOMISE - select DVB_S5H1411 if !DVB_FE_CUSTOMISE - select DVB_LGDT330X if !DVB_FE_CUSTOMISE - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select DVB_TDA10048 if !DVB_FE_CUSTOMIZE - select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE - select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE - select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE - select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE - ---help--- - This is a video4linux driver for Conexant 23885 based - TV cards. - - To compile this driver as a module, choose M here: the - module will be called cx23885 - diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile deleted file mode 100644 index 29c23b44c13..00000000000 --- a/drivers/media/video/cx23885/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o - -obj-$(CONFIG_VIDEO_CX23885) += cx23885.o - -EXTRA_CFLAGS += -Idrivers/media/video -EXTRA_CFLAGS += -Idrivers/media/common/tuners -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends - -EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c deleted file mode 100644 index bfe25841dbf..00000000000 --- a/drivers/media/video/cx23885/cx23885-417.c +++ /dev/null @@ -1,1821 +0,0 @@ -/* - * - * Support for a cx23417 mpeg encoder via cx23885 host port. - * - * (c) 2004 Jelle Foks <jelle@foks.us> - * (c) 2004 Gerd Knorr <kraxel@bytesex.org> - * (c) 2008 Steven Toth <stoth@linuxtv.org> - * - CX23885/7/8 support - * - * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/), - * - * 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/moduleparam.h> -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include <media/cx2341x.h> - -#include "cx23885.h" - -#define CX23885_FIRM_IMAGE_SIZE 376836 -#define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" - -static unsigned int mpegbufs = 32; -module_param(mpegbufs, int, 0644); -MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32"); -static unsigned int mpeglines = 32; -module_param(mpeglines, int, 0644); -MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32"); -static unsigned int mpeglinesize = 512; -module_param(mpeglinesize, int, 0644); -MODULE_PARM_DESC(mpeglinesize, - "number of bytes in each line of an MPEG buffer, range 512-1024"); - -static unsigned int v4l_debug; -module_param(v4l_debug, int, 0644); -MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); - -#define dprintk(level, fmt, arg...)\ - do { if (v4l_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg);\ - } while (0) - -static struct cx23885_tvnorm cx23885_tvnorms[] = { - { - .name = "NTSC-M", - .id = V4L2_STD_NTSC_M, - }, { - .name = "NTSC-JP", - .id = V4L2_STD_NTSC_M_JP, - }, { - .name = "PAL-BG", - .id = V4L2_STD_PAL_BG, - }, { - .name = "PAL-DK", - .id = V4L2_STD_PAL_DK, - }, { - .name = "PAL-I", - .id = V4L2_STD_PAL_I, - }, { - .name = "PAL-M", - .id = V4L2_STD_PAL_M, - }, { - .name = "PAL-N", - .id = V4L2_STD_PAL_N, - }, { - .name = "PAL-Nc", - .id = V4L2_STD_PAL_Nc, - }, { - .name = "PAL-60", - .id = V4L2_STD_PAL_60, - }, { - .name = "SECAM-L", - .id = V4L2_STD_SECAM_L, - }, { - .name = "SECAM-DK", - .id = V4L2_STD_SECAM_DK, - } -}; - -/* ------------------------------------------------------------------ */ -enum cx23885_capture_type { - CX23885_MPEG_CAPTURE, - CX23885_RAW_CAPTURE, - CX23885_RAW_PASSTHRU_CAPTURE -}; -enum cx23885_capture_bits { - CX23885_RAW_BITS_NONE = 0x00, - CX23885_RAW_BITS_YUV_CAPTURE = 0x01, - CX23885_RAW_BITS_PCM_CAPTURE = 0x02, - CX23885_RAW_BITS_VBI_CAPTURE = 0x04, - CX23885_RAW_BITS_PASSTHRU_CAPTURE = 0x08, - CX23885_RAW_BITS_TO_HOST_CAPTURE = 0x10 -}; -enum cx23885_capture_end { - CX23885_END_AT_GOP, /* stop at the end of gop, generate irq */ - CX23885_END_NOW, /* stop immediately, no irq */ -}; -enum cx23885_framerate { - CX23885_FRAMERATE_NTSC_30, /* NTSC: 30fps */ - CX23885_FRAMERATE_PAL_25 /* PAL: 25fps */ -}; -enum cx23885_stream_port { - CX23885_OUTPUT_PORT_MEMORY, - CX23885_OUTPUT_PORT_STREAMING, - CX23885_OUTPUT_PORT_SERIAL -}; -enum cx23885_data_xfer_status { - CX23885_MORE_BUFFERS_FOLLOW, - CX23885_LAST_BUFFER, -}; -enum cx23885_picture_mask { - CX23885_PICTURE_MASK_NONE, - CX23885_PICTURE_MASK_I_FRAMES, - CX23885_PICTURE_MASK_I_P_FRAMES = 0x3, - CX23885_PICTURE_MASK_ALL_FRAMES = 0x7, -}; -enum cx23885_vbi_mode_bits { - CX23885_VBI_BITS_SLICED, - CX23885_VBI_BITS_RAW, -}; -enum cx23885_vbi_insertion_bits { - CX23885_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, - CX23885_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, - CX23885_VBI_BITS_SEPARATE_STREAM = 0x2 << 1, - CX23885_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, - CX23885_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, -}; -enum cx23885_dma_unit { - CX23885_DMA_BYTES, - CX23885_DMA_FRAMES, -}; -enum cx23885_dma_transfer_status_bits { - CX23885_DMA_TRANSFER_BITS_DONE = 0x01, - CX23885_DMA_TRANSFER_BITS_ERROR = 0x04, - CX23885_DMA_TRANSFER_BITS_LL_ERROR = 0x10, -}; -enum cx23885_pause { - CX23885_PAUSE_ENCODING, - CX23885_RESUME_ENCODING, -}; -enum cx23885_copyright { - CX23885_COPYRIGHT_OFF, - CX23885_COPYRIGHT_ON, -}; -enum cx23885_notification_type { - CX23885_NOTIFICATION_REFRESH, -}; -enum cx23885_notification_status { - CX23885_NOTIFICATION_OFF, - CX23885_NOTIFICATION_ON, -}; -enum cx23885_notification_mailbox { - CX23885_NOTIFICATION_NO_MAILBOX = -1, -}; -enum cx23885_field1_lines { - CX23885_FIELD1_SAA7114 = 0x00EF, /* 239 */ - CX23885_FIELD1_SAA7115 = 0x00F0, /* 240 */ - CX23885_FIELD1_MICRONAS = 0x0105, /* 261 */ -}; -enum cx23885_field2_lines { - CX23885_FIELD2_SAA7114 = 0x00EF, /* 239 */ - CX23885_FIELD2_SAA7115 = 0x00F0, /* 240 */ - CX23885_FIELD2_MICRONAS = 0x0106, /* 262 */ -}; -enum cx23885_custom_data_type { - CX23885_CUSTOM_EXTENSION_USR_DATA, - CX23885_CUSTOM_PRIVATE_PACKET, -}; -enum cx23885_mute { - CX23885_UNMUTE, - CX23885_MUTE, -}; -enum cx23885_mute_video_mask { - CX23885_MUTE_VIDEO_V_MASK = 0x0000FF00, - CX23885_MUTE_VIDEO_U_MASK = 0x00FF0000, - CX23885_MUTE_VIDEO_Y_MASK = 0xFF000000, -}; -enum cx23885_mute_video_shift { - CX23885_MUTE_VIDEO_V_SHIFT = 8, - CX23885_MUTE_VIDEO_U_SHIFT = 16, - CX23885_MUTE_VIDEO_Y_SHIFT = 24, -}; - -/* defines below are from ivtv-driver.h */ -#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF - -/* Firmware API commands */ -#define IVTV_API_STD_TIMEOUT 500 - -/* Registers */ -/* IVTV_REG_OFFSET */ -#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) -#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) -#define IVTV_REG_SPU (0x9050) -#define IVTV_REG_HW_BLOCKS (0x9054) -#define IVTV_REG_VPU (0x9058) -#define IVTV_REG_APU (0xA064) - -/**** Bit definitions for MC417_RWD and MC417_OEN registers *** - bits 31-16 -+-----------+ -| Reserved | -+-----------+ - bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 -+-------+-------+-------+-------+-------+-------+-------+-------+ -| MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0| -+-------+-------+-------+-------+-------+-------+-------+-------+ - bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 -+-------+-------+-------+-------+-------+-------+-------+-------+ -|MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0| -+-------+-------+-------+-------+-------+-------+-------+-------+ -***/ -#define MC417_MIWR 0x8000 -#define MC417_MIRD 0x4000 -#define MC417_MICS 0x2000 -#define MC417_MIRDY 0x1000 -#define MC417_MIADDR 0x0F00 -#define MC417_MIDATA 0x00FF - -/* MIADDR* nibble definitions */ -#define MCI_MEMORY_DATA_BYTE0 0x000 -#define MCI_MEMORY_DATA_BYTE1 0x100 -#define MCI_MEMORY_DATA_BYTE2 0x200 -#define MCI_MEMORY_DATA_BYTE3 0x300 -#define MCI_MEMORY_ADDRESS_BYTE2 0x400 -#define MCI_MEMORY_ADDRESS_BYTE1 0x500 -#define MCI_MEMORY_ADDRESS_BYTE0 0x600 -#define MCI_REGISTER_DATA_BYTE0 0x800 -#define MCI_REGISTER_DATA_BYTE1 0x900 -#define MCI_REGISTER_DATA_BYTE2 0xA00 -#define MCI_REGISTER_DATA_BYTE3 0xB00 -#define MCI_REGISTER_ADDRESS_BYTE0 0xC00 -#define MCI_REGISTER_ADDRESS_BYTE1 0xD00 -#define MCI_REGISTER_MODE 0xE00 - -/* Read and write modes */ -#define MCI_MODE_REGISTER_READ 0 -#define MCI_MODE_REGISTER_WRITE 1 -#define MCI_MODE_MEMORY_READ 0 -#define MCI_MODE_MEMORY_WRITE 0x40 - -/*** Bit definitions for MC417_CTL register **** - bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0 -+--------+-------------+--------+--------------+------------+ -|Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN| -+--------+-------------+--------+--------------+------------+ -***/ -#define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030) -#define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006) -#define MC417_UART_GPIO_EN 0x00000001 - -/* Values for speed control */ -#define MC417_SPD_CTL_SLOW 0x1 -#define MC417_SPD_CTL_MEDIUM 0x0 -#define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */ - -/* Values for GPIO select */ -#define MC417_GPIO_SEL_GPIO3 0x3 -#define MC417_GPIO_SEL_GPIO2 0x2 -#define MC417_GPIO_SEL_GPIO1 0x1 -#define MC417_GPIO_SEL_GPIO0 0x0 - -void cx23885_mc417_init(struct cx23885_dev *dev) -{ - u32 regval; - - dprintk(2, "%s()\n", __func__); - - /* Configure MC417_CTL register to defaults. */ - regval = MC417_SPD_CTL(MC417_SPD_CTL_FAST) | - MC417_GPIO_SEL(MC417_GPIO_SEL_GPIO3) | - MC417_UART_GPIO_EN; - cx_write(MC417_CTL, regval); - - /* Configure MC417_OEN to defaults. */ - regval = MC417_MIRDY; - cx_write(MC417_OEN, regval); - - /* Configure MC417_RWD to defaults. */ - regval = MC417_MIWR | MC417_MIRD | MC417_MICS; - cx_write(MC417_RWD, regval); -} - -static int mc417_wait_ready(struct cx23885_dev *dev) -{ - u32 mi_ready; - unsigned long timeout = jiffies + msecs_to_jiffies(1); - - for (;;) { - mi_ready = cx_read(MC417_RWD) & MC417_MIRDY; - if (mi_ready != 0) - return 0; - if (time_after(jiffies, timeout)) - return -1; - udelay(1); - } -} - -static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value) -{ - u32 regval; - - /* Enable MC417 GPIO outputs except for MC417_MIRDY, - * which is an input. - */ - cx_write(MC417_OEN, MC417_MIRDY); - - /* Write data byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0 | - (value & 0x000000FF); - cx_write(MC417_RWD, regval); - - /* Transition CS/WR to effect write transaction across bus. */ - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1 | - ((value >> 8) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2 | - ((value >> 16) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 3 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3 | - ((value >> 24) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 | - (address & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 | - ((address >> 8) & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Indicate that this is a write. */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE | - MCI_MODE_REGISTER_WRITE; - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Wait for the trans to complete (MC417_MIRDY asserted). */ - return mc417_wait_ready(dev); -} - -static int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value) -{ - int retval; - u32 regval; - u32 tempval; - u32 dataval; - - /* Enable MC417 GPIO outputs except for MC417_MIRDY, - * which is an input. - */ - cx_write(MC417_OEN, MC417_MIRDY); - - /* Write address byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 | - ((address & 0x00FF)); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 | - ((address >> 8) & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Indicate that this is a register read. */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE | - MCI_MODE_REGISTER_READ; - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Wait for the trans to complete (MC417_MIRDY asserted). */ - retval = mc417_wait_ready(dev); - - /* switch the DAT0-7 GPIO[10:3] to input mode */ - cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA); - - /* Read data byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0; - cx_write(MC417_RWD, regval); - - /* Transition RD to effect read transaction across bus. - * Transtion 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)? - * Should it be 0x9000 -> 0xF000 (also why is RDY being set, its - * input only...) - */ - regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0; - cx_write(MC417_RWD, regval); - - /* Collect byte */ - tempval = cx_read(MC417_RWD); - dataval = tempval & 0x000000FF; - - /* Bring CS and RD high. */ - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 8); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 16); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 3 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 24); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - *value = dataval; - - return retval; -} - -int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value) -{ - u32 regval; - - /* Enable MC417 GPIO outputs except for MC417_MIRDY, - * which is an input. - */ - cx_write(MC417_OEN, MC417_MIRDY); - - /* Write data byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0 | - (value & 0x000000FF); - cx_write(MC417_RWD, regval); - - /* Transition CS/WR to effect write transaction across bus. */ - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1 | - ((value >> 8) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2 | - ((value >> 16) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 3 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3 | - ((value >> 24) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 | - MCI_MODE_MEMORY_WRITE | ((address >> 16) & 0x3F); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 | - ((address >> 8) & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 | - (address & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Wait for the trans to complete (MC417_MIRDY asserted). */ - return mc417_wait_ready(dev); -} - -int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value) -{ - int retval; - u32 regval; - u32 tempval; - u32 dataval; - - /* Enable MC417 GPIO outputs except for MC417_MIRDY, - * which is an input. - */ - cx_write(MC417_OEN, MC417_MIRDY); - - /* Write address byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 | - MCI_MODE_MEMORY_READ | ((address >> 16) & 0x3F); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 | - ((address >> 8) & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 | - (address & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Wait for the trans to complete (MC417_MIRDY asserted). */ - retval = mc417_wait_ready(dev); - - /* switch the DAT0-7 GPIO[10:3] to input mode */ - cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA); - - /* Read data byte 3 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3; - cx_write(MC417_RWD, regval); - - /* Transition RD to effect read transaction across bus. */ - regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3; - cx_write(MC417_RWD, regval); - - /* Collect byte */ - tempval = cx_read(MC417_RWD); - dataval = ((tempval & 0x000000FF) << 24); - - /* Bring CS and RD high. */ - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 16); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 8); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= (tempval & 0x000000FF); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - *value = dataval; - - return retval; -} - -/* ------------------------------------------------------------------ */ - -/* MPEG encoder API */ -static char *cmd_to_str(int cmd) -{ - switch (cmd) { - case CX2341X_ENC_PING_FW: - return "PING_FW"; - case CX2341X_ENC_START_CAPTURE: - return "START_CAPTURE"; - case CX2341X_ENC_STOP_CAPTURE: - return "STOP_CAPTURE"; - case CX2341X_ENC_SET_AUDIO_ID: - return "SET_AUDIO_ID"; - case CX2341X_ENC_SET_VIDEO_ID: - return "SET_VIDEO_ID"; - case CX2341X_ENC_SET_PCR_ID: - return "SET_PCR_PID"; - case CX2341X_ENC_SET_FRAME_RATE: - return "SET_FRAME_RATE"; - case CX2341X_ENC_SET_FRAME_SIZE: - return "SET_FRAME_SIZE"; - case CX2341X_ENC_SET_BIT_RATE: - return "SET_BIT_RATE"; - case CX2341X_ENC_SET_GOP_PROPERTIES: - return "SET_GOP_PROPERTIES"; - case CX2341X_ENC_SET_ASPECT_RATIO: - return "SET_ASPECT_RATIO"; - case CX2341X_ENC_SET_DNR_FILTER_MODE: - return "SET_DNR_FILTER_PROPS"; - case CX2341X_ENC_SET_DNR_FILTER_PROPS: - return "SET_DNR_FILTER_PROPS"; - case CX2341X_ENC_SET_CORING_LEVELS: - return "SET_CORING_LEVELS"; - case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE: - return "SET_SPATIAL_FILTER_TYPE"; - case CX2341X_ENC_SET_VBI_LINE: - return "SET_VBI_LINE"; - case CX2341X_ENC_SET_STREAM_TYPE: - return "SET_STREAM_TYPE"; - case CX2341X_ENC_SET_OUTPUT_PORT: - return "SET_OUTPUT_PORT"; - case CX2341X_ENC_SET_AUDIO_PROPERTIES: - return "SET_AUDIO_PROPERTIES"; - case CX2341X_ENC_HALT_FW: - return "HALT_FW"; - case CX2341X_ENC_GET_VERSION: - return "GET_VERSION"; - case CX2341X_ENC_SET_GOP_CLOSURE: - return "SET_GOP_CLOSURE"; - case CX2341X_ENC_GET_SEQ_END: - return "GET_SEQ_END"; - case CX2341X_ENC_SET_PGM_INDEX_INFO: - return "SET_PGM_INDEX_INFO"; - case CX2341X_ENC_SET_VBI_CONFIG: - return "SET_VBI_CONFIG"; - case CX2341X_ENC_SET_DMA_BLOCK_SIZE: - return "SET_DMA_BLOCK_SIZE"; - case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10: - return "GET_PREV_DMA_INFO_MB_10"; - case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9: - return "GET_PREV_DMA_INFO_MB_9"; - case CX2341X_ENC_SCHED_DMA_TO_HOST: - return "SCHED_DMA_TO_HOST"; - case CX2341X_ENC_INITIALIZE_INPUT: - return "INITIALIZE_INPUT"; - case CX2341X_ENC_SET_FRAME_DROP_RATE: - return "SET_FRAME_DROP_RATE"; - case CX2341X_ENC_PAUSE_ENCODER: - return "PAUSE_ENCODER"; - case CX2341X_ENC_REFRESH_INPUT: - return "REFRESH_INPUT"; - case CX2341X_ENC_SET_COPYRIGHT: - return "SET_COPYRIGHT"; - case CX2341X_ENC_SET_EVENT_NOTIFICATION: - return "SET_EVENT_NOTIFICATION"; - case CX2341X_ENC_SET_NUM_VSYNC_LINES: - return "SET_NUM_VSYNC_LINES"; - case CX2341X_ENC_SET_PLACEHOLDER: - return "SET_PLACEHOLDER"; - case CX2341X_ENC_MUTE_VIDEO: - return "MUTE_VIDEO"; - case CX2341X_ENC_MUTE_AUDIO: - return "MUTE_AUDIO"; - case CX2341X_ENC_MISC: - return "MISC"; - default: - return "UNKNOWN"; - } -} - -static int cx23885_mbox_func(void *priv, - u32 command, - int in, - int out, - u32 data[CX2341X_MBOX_MAX_DATA]) -{ - struct cx23885_dev *dev = priv; - unsigned long timeout; - u32 value, flag, retval = 0; - int i; - - dprintk(3, "%s: command(0x%X) = %s\n", __func__, command, - cmd_to_str(command)); - - /* this may not be 100% safe if we can't read any memory location - without side effects */ - mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value); - if (value != 0x12345678) { - printk(KERN_ERR - "Firmware and/or mailbox pointer not initialized " - "or corrupted, signature = 0x%x, cmd = %s\n", value, - cmd_to_str(command)); - return -1; - } - - /* This read looks at 32 bits, but flag is only 8 bits. - * Seems we also bail if CMD or TIMEOUT bytes are set??? - */ - mc417_memory_read(dev, dev->cx23417_mailbox, &flag); - if (flag) { - printk(KERN_ERR "ERROR: Mailbox appears to be in use " - "(%x), cmd = %s\n", flag, cmd_to_str(command)); - return -1; - } - - flag |= 1; /* tell 'em we're working on it */ - mc417_memory_write(dev, dev->cx23417_mailbox, flag); - - /* write command + args + fill remaining with zeros */ - /* command code */ - mc417_memory_write(dev, dev->cx23417_mailbox + 1, command); - mc417_memory_write(dev, dev->cx23417_mailbox + 3, - IVTV_API_STD_TIMEOUT); /* timeout */ - for (i = 0; i < in; i++) { - mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, data[i]); - dprintk(3, "API Input %d = %d\n", i, data[i]); - } - for (; i < CX2341X_MBOX_MAX_DATA; i++) - mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, 0); - - flag |= 3; /* tell 'em we're done writing */ - mc417_memory_write(dev, dev->cx23417_mailbox, flag); - - /* wait for firmware to handle the API command */ - timeout = jiffies + msecs_to_jiffies(10); - for (;;) { - mc417_memory_read(dev, dev->cx23417_mailbox, &flag); - if (0 != (flag & 4)) - break; - if (time_after(jiffies, timeout)) { - printk(KERN_ERR "ERROR: API Mailbox timeout\n"); - return -1; - } - udelay(10); - } - - /* read output values */ - for (i = 0; i < out; i++) { - mc417_memory_read(dev, dev->cx23417_mailbox + 4 + i, data + i); - dprintk(3, "API Output %d = %d\n", i, data[i]); - } - - mc417_memory_read(dev, dev->cx23417_mailbox + 2, &retval); - dprintk(3, "API result = %d\n", retval); - - flag = 0; - mc417_memory_write(dev, dev->cx23417_mailbox, flag); - - return retval; -} - -/* We don't need to call the API often, so using just one - * mailbox will probably suffice - */ -static int cx23885_api_cmd(struct cx23885_dev *dev, - u32 command, - u32 inputcnt, - u32 outputcnt, - ...) -{ - u32 data[CX2341X_MBOX_MAX_DATA]; - va_list vargs; - int i, err; - - dprintk(3, "%s() cmds = 0x%08x\n", __func__, command); - - va_start(vargs, outputcnt); - for (i = 0; i < inputcnt; i++) - data[i] = va_arg(vargs, int); - - err = cx23885_mbox_func(dev, command, inputcnt, outputcnt, data); - for (i = 0; i < outputcnt; i++) { - int *vptr = va_arg(vargs, int *); - *vptr = data[i]; - } - va_end(vargs); - - return err; -} - -static int cx23885_find_mailbox(struct cx23885_dev *dev) -{ - u32 signature[4] = { - 0x12345678, 0x34567812, 0x56781234, 0x78123456 - }; - int signaturecnt = 0; - u32 value; - int i; - - dprintk(2, "%s()\n", __func__); - - for (i = 0; i < CX23885_FIRM_IMAGE_SIZE; i++) { - mc417_memory_read(dev, i, &value); - if (value == signature[signaturecnt]) - signaturecnt++; - else - signaturecnt = 0; - if (4 == signaturecnt) { - dprintk(1, "Mailbox signature found at 0x%x\n", i+1); - return i+1; - } - } - printk(KERN_ERR "Mailbox signature values not found!\n"); - return -1; -} - -static int cx23885_load_firmware(struct cx23885_dev *dev) -{ - static const unsigned char magic[8] = { - 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa - }; - const struct firmware *firmware; - int i, retval = 0; - u32 value = 0; - u32 gpio_output = 0; - u32 checksum = 0; - u32 *dataptr; - - dprintk(2, "%s()\n", __func__); - - /* Save GPIO settings before reset of APU */ - retval |= mc417_memory_read(dev, 0x9020, &gpio_output); - retval |= mc417_memory_read(dev, 0x900C, &value); - - retval = mc417_register_write(dev, - IVTV_REG_VPU, 0xFFFFFFED); - retval |= mc417_register_write(dev, - IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); - retval |= mc417_register_write(dev, - IVTV_REG_ENC_SDRAM_REFRESH, 0x80000800); - retval |= mc417_register_write(dev, - IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); - retval |= mc417_register_write(dev, - IVTV_REG_APU, 0); - - if (retval != 0) { - printk(KERN_ERR "%s: Error with mc417_register_write\n", - __func__); - return -1; - } - - retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME, - &dev->pci->dev); - - if (retval != 0) { - printk(KERN_ERR - "ERROR: Hotplug firmware request failed (%s).\n", - CX2341X_FIRM_ENC_FILENAME); - printk(KERN_ERR "Please fix your hotplug setup, the board will " - "not work without firmware loaded!\n"); - return -1; - } - - if (firmware->size != CX23885_FIRM_IMAGE_SIZE) { - printk(KERN_ERR "ERROR: Firmware size mismatch " - "(have %zd, expected %d)\n", - firmware->size, CX23885_FIRM_IMAGE_SIZE); - release_firmware(firmware); - return -1; - } - - if (0 != memcmp(firmware->data, magic, 8)) { - printk(KERN_ERR - "ERROR: Firmware magic mismatch, wrong file?\n"); - release_firmware(firmware); - return -1; - } - - /* transfer to the chip */ - dprintk(2, "Loading firmware ...\n"); - dataptr = (u32 *)firmware->data; - for (i = 0; i < (firmware->size >> 2); i++) { - value = *dataptr; - checksum += ~value; - if (mc417_memory_write(dev, i, value) != 0) { - printk(KERN_ERR "ERROR: Loading firmware failed!\n"); - release_firmware(firmware); - return -1; - } - dataptr++; - } - - /* read back to verify with the checksum */ - dprintk(1, "Verifying firmware ...\n"); - for (i--; i >= 0; i--) { - if (mc417_memory_read(dev, i, &value) != 0) { - printk(KERN_ERR "ERROR: Reading firmware failed!\n"); - release_firmware(firmware); - return -1; - } - checksum -= ~value; - } - if (checksum) { - printk(KERN_ERR - "ERROR: Firmware load failed (checksum mismatch).\n"); - release_firmware(firmware); - return -1; - } - release_firmware(firmware); - dprintk(1, "Firmware upload successful.\n"); - - retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, - IVTV_CMD_HW_BLOCKS_RST); - - /* Restore GPIO settings, make sure EIO14 is enabled as an output. */ - dprintk(2, "%s: GPIO output EIO 0-15 was = 0x%x\n", - __func__, gpio_output); - /* Power-up seems to have GPIOs AFU. This was causing digital side - * to fail at power-up. Seems GPIOs should be set to 0x10ff0411 at - * power-up. - * gpio_output |= (1<<14); - */ - /* Note: GPIO14 is specific to the HVR1800 here */ - gpio_output = 0x10ff0411 | (1<<14); - retval |= mc417_register_write(dev, 0x9020, gpio_output | (1<<14)); - dprintk(2, "%s: GPIO output EIO 0-15 now = 0x%x\n", - __func__, gpio_output); - - dprintk(1, "%s: GPIO value EIO 0-15 was = 0x%x\n", - __func__, value); - value |= (1<<14); - dprintk(1, "%s: GPIO value EIO 0-15 now = 0x%x\n", - __func__, value); - retval |= mc417_register_write(dev, 0x900C, value); - - retval |= mc417_register_read(dev, IVTV_REG_VPU, &value); - retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8); - - if (retval < 0) - printk(KERN_ERR "%s: Error with mc417_register_write\n", - __func__); - return 0; -} - -void cx23885_417_check_encoder(struct cx23885_dev *dev) -{ - u32 status, seq; - - status = seq = 0; - cx23885_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq); - dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq); -} - -static void cx23885_codec_settings(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - /* assign frame size */ - cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, - dev->ts1.height, dev->ts1.width); - - dev->mpeg_params.width = dev->ts1.width; - dev->mpeg_params.height = dev->ts1.height; - dev->mpeg_params.is_50hz = - (dev->encodernorm.id & V4L2_STD_625_50) != 0; - - cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params); - - cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1); - cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1); -} - -static int cx23885_initialize_codec(struct cx23885_dev *dev) -{ - int version; - int retval; - u32 i, data[7]; - - dprintk(1, "%s()\n", __func__); - - retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ - if (retval < 0) { - dprintk(2, "%s() PING OK\n", __func__); - retval = cx23885_load_firmware(dev); - if (retval < 0) { - printk(KERN_ERR "%s() f/w load failed\n", __func__); - return retval; - } - retval = cx23885_find_mailbox(dev); - if (retval < 0) { - printk(KERN_ERR "%s() mailbox < 0, error\n", - __func__); - return -1; - } - dev->cx23417_mailbox = retval; - retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); - if (retval < 0) { - printk(KERN_ERR - "ERROR: cx23417 firmware ping failed!\n"); - return -1; - } - retval = cx23885_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, - &version); - if (retval < 0) { - printk(KERN_ERR "ERROR: cx23417 firmware get encoder :" - "version failed!\n"); - return -1; - } - dprintk(1, "cx23417 firmware version is 0x%08x\n", version); - msleep(200); - } - - cx23885_codec_settings(dev); - msleep(60); - - cx23885_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, - CX23885_FIELD1_SAA7115, CX23885_FIELD2_SAA7115); - cx23885_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, - CX23885_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0); - - /* Setup to capture VBI */ - data[0] = 0x0001BD00; - data[1] = 1; /* frames per interrupt */ - data[2] = 4; /* total bufs */ - data[3] = 0x91559155; /* start codes */ - data[4] = 0x206080C0; /* stop codes */ - data[5] = 6; /* lines */ - data[6] = 64; /* BPL */ - - cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1], - data[2], data[3], data[4], data[5], data[6]); - - for (i = 2; i <= 24; i++) { - int valid; - - valid = ((i >= 19) && (i <= 21)); - cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i, - valid, 0 , 0, 0); - cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, - i | 0x80000000, valid, 0, 0, 0); - } - - cx23885_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX23885_UNMUTE); - msleep(60); - - /* initialize the video input */ - cx23885_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0); - msleep(60); - - /* Enable VIP style pixel invalidation so we work with scaled mode */ - mc417_memory_write(dev, 2120, 0x00000080); - - /* start capturing to the host interface */ - cx23885_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, - CX23885_MPEG_CAPTURE, CX23885_RAW_BITS_NONE); - msleep(10); - - return 0; -} - -/* ------------------------------------------------------------------ */ - -static int bb_buf_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) -{ - struct cx23885_fh *fh = q->priv_data; - - fh->dev->ts1.ts_packet_size = mpeglinesize; - fh->dev->ts1.ts_packet_count = mpeglines; - - *size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count; - *count = mpegbufs; - - return 0; -} - -static int bb_buf_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, enum v4l2_field field) -{ - struct cx23885_fh *fh = q->priv_data; - return cx23885_buf_prepare(q, &fh->dev->ts1, - (struct cx23885_buffer *)vb, - field); -} - -static void bb_buf_queue(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - struct cx23885_fh *fh = q->priv_data; - cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb); -} - -static void bb_buf_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - cx23885_free_buffer(q, (struct cx23885_buffer *)vb); -} - -static struct videobuf_queue_ops cx23885_qops = { - .buf_setup = bb_buf_setup, - .buf_prepare = bb_buf_prepare, - .buf_queue = bb_buf_queue, - .buf_release = bb_buf_release, -}; - -/* ------------------------------------------------------------------ */ - -static const u32 *ctrl_classes[] = { - cx2341x_mpeg_ctrls, - NULL -}; - -static int cx23885_queryctrl(struct cx23885_dev *dev, - struct v4l2_queryctrl *qctrl) -{ - qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); - if (qctrl->id == 0) - return -EINVAL; - - /* MPEG V4L2 controls */ - if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl)) - qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; - - return 0; -} - -static int cx23885_querymenu(struct cx23885_dev *dev, - struct v4l2_querymenu *qmenu) -{ - struct v4l2_queryctrl qctrl; - - qctrl.id = qmenu->id; - cx23885_queryctrl(dev, &qctrl); - return v4l2_ctrl_query_menu(qmenu, &qctrl, - cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id)); -} - -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++) - if (*id & cx23885_tvnorms[i].id) - break; - if (i == ARRAY_SIZE(cx23885_tvnorms)) - return -EINVAL; - dev->encodernorm = cx23885_tvnorms[i]; - return 0; -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_input *input; - unsigned int n; - - n = i->index; - - if (n >= 4) - return -EINVAL; - - input = &cx23885_boards[dev->board].input[n]; - - if (input->type == 0) - return -EINVAL; - - memset(i, 0, sizeof(*i)); - i->index = n; - - /* FIXME - * strcpy(i->name, input->name); */ - strcpy(i->name, "unset"); - - if (input->type == CX23885_VMUX_TELEVISION || - input->type == CX23885_VMUX_CABLE) - i->type = V4L2_INPUT_TYPE_TUNER; - else - i->type = V4L2_INPUT_TYPE_CAMERA; - - for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++) - i->std |= cx23885_tvnorms[n].id; - return 0; -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - *i = dev->input; - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - if (i >= 4) - return -EINVAL; - - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - if (UNSET == dev->tuner_type) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - memset(t, 0, sizeof(*t)); - strcpy(t->name, "Television"); - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t); - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t); - - dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type); - - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - if (UNSET == dev->tuner_type) - return -EINVAL; - - /* Update the A/V core */ - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t); - - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - memset(f, 0, sizeof(*f)); - if (UNSET == dev->tuner_type) - return -EINVAL; - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = dev->freq; - - /* Assumption that tuner is always on bus 1 */ - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f); - - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, - CX23885_END_NOW, CX23885_MPEG_CAPTURE, - CX23885_RAW_BITS_NONE); - - dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n", - dev->tuner_type); - dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n", - f->tuner, f->type); - if (UNSET == dev->tuner_type) - return -EINVAL; - if (f->tuner != 0) - return -EINVAL; - if (f->type != V4L2_TUNER_ANALOG_TV) - return -EINVAL; - dev->freq = f->frequency; - - /* Assumption that tuner is always on bus 1 */ - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f); - - cx23885_initialize_codec(dev); - - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - /* Update the A/V core */ - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl); - return 0; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_tsport *tsport = &dev->ts1; - - memset(cap, 0, sizeof(*cap)); - strcpy(cap->driver, dev->name); - strlcpy(cap->card, cx23885_boards[tsport->dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - cap->version = CX23885_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING | - 0; - if (UNSET != dev->tuner_type) - cap->capabilities |= V4L2_CAP_TUNER; - - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - int index; - - index = f->index; - if (index != 0) - return -EINVAL; - - memset(f, 0, sizeof(*f)); - f->index = index; - strlcpy(f->description, "MPEG", sizeof(f->description)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->pixelformat = V4L2_PIX_FMT_MPEG; - - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - memset(f, 0, sizeof(*f)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - f->fmt.pix.width = dev->ts1.width; - f->fmt.pix.height = dev->ts1.height; - f->fmt.pix.field = fh->mpegq.field; - dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", - dev->ts1.width, dev->ts1.height, fh->mpegq.field); - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.sizeimage = - f->fmt.pix.colorspace = 0; - dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", - dev->ts1.width, dev->ts1.height, fh->mpegq.field); - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); - return 0; -} - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_reqbufs(&fh->mpegq, p); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_querybuf(&fh->mpegq, p); -} - -static int vidioc_qbuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_qbuf(&fh->mpegq, p); -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct cx23885_fh *fh = priv; - - return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK); -} - - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type i) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_streamon(&fh->mpegq); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_streamoff(&fh->mpegq); -} - -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS); -} - -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - struct cx2341x_mpeg_params p; - int err; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - - p = dev->mpeg_params; - err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS); - - if (err == 0) { - err = cx2341x_update(dev, cx23885_mbox_func, - &dev->mpeg_params, &p); - dev->mpeg_params = p; - } - return err; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - struct cx2341x_mpeg_params p; - int err; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - - p = dev->mpeg_params; - err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS); - return err; -} - -static int vidioc_log_status(struct file *file, void *priv) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - char name[32 + 2]; - - snprintf(name, sizeof(name), "%s/2", dev->name); - printk(KERN_INFO - "%s/2: ============ START LOG STATUS ============\n", - dev->name); - cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS, - NULL); - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS, - NULL); - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS, - NULL); - cx2341x_log_status(&dev->mpeg_params, name); - printk(KERN_INFO - "%s/2: ============= END LOG STATUS =============\n", - dev->name); - return 0; -} - -static int vidioc_querymenu(struct file *file, void *priv, - struct v4l2_querymenu *a) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - return cx23885_querymenu(dev, a); -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - return cx23885_queryctrl(dev, c); -} - -static int mpeg_open(struct file *file) -{ - int minor = video_devdata(file)->minor; - struct cx23885_dev *h, *dev = NULL; - struct list_head *list; - struct cx23885_fh *fh; - - dprintk(2, "%s()\n", __func__); - - lock_kernel(); - list_for_each(list, &cx23885_devlist) { - h = list_entry(list, struct cx23885_dev, devlist); - if (h->v4l_device && - h->v4l_device->minor == minor) { - dev = h; - break; - } - } - - if (dev == NULL) { - unlock_kernel(); - return -ENODEV; - } - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); - return -ENOMEM; - } - - file->private_data = fh; - fh->dev = dev; - - videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops, - &dev->pci->dev, &dev->ts1.slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct cx23885_buffer), - fh); - unlock_kernel(); - - return 0; -} - -static int mpeg_release(struct file *file) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - dprintk(2, "%s()\n", __func__); - - /* FIXME: Review this crap */ - /* Shut device down on last close */ - if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { - if (atomic_dec_return(&dev->v4l_reader_count) == 0) { - /* stop mpeg capture */ - cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, - CX23885_END_NOW, CX23885_MPEG_CAPTURE, - CX23885_RAW_BITS_NONE); - - msleep(500); - cx23885_417_check_encoder(dev); - - cx23885_cancel_buffers(&fh->dev->ts1); - } - } - - if (fh->mpegq.streaming) - videobuf_streamoff(&fh->mpegq); - if (fh->mpegq.reading) - videobuf_read_stop(&fh->mpegq); - - videobuf_mmap_free(&fh->mpegq); - file->private_data = NULL; - kfree(fh); - - return 0; -} - -static ssize_t mpeg_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - dprintk(2, "%s()\n", __func__); - - /* Deal w/ A/V decoder * and mpeg encoder sync issues. */ - /* Start mpeg encoder on first read. */ - if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { - if (atomic_inc_return(&dev->v4l_reader_count) == 1) { - if (cx23885_initialize_codec(dev) < 0) - return -EINVAL; - } - } - - return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0, - file->f_flags & O_NONBLOCK); -} - -static unsigned int mpeg_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - dprintk(2, "%s\n", __func__); - - return videobuf_poll_stream(file, &fh->mpegq, wait); -} - -static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - dprintk(2, "%s()\n", __func__); - - return videobuf_mmap_mapper(&fh->mpegq, vma); -} - -static struct v4l2_file_operations mpeg_fops = { - .owner = THIS_MODULE, - .open = mpeg_open, - .release = mpeg_release, - .read = mpeg_read, - .poll = mpeg_poll, - .mmap = mpeg_mmap, -}; - -static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, - .vidioc_log_status = vidioc_log_status, - .vidioc_querymenu = vidioc_querymenu, - .vidioc_queryctrl = vidioc_queryctrl, -}; - -static struct video_device cx23885_mpeg_template = { - .name = "cx23885", - .fops = &mpeg_fops, - .ioctl_ops = &mpeg_ioctl_ops, - .minor = -1, -}; - -void cx23885_417_unregister(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - if (dev->v4l_device) { - if (-1 != dev->v4l_device->minor) - video_unregister_device(dev->v4l_device); - else - video_device_release(dev->v4l_device); - dev->v4l_device = NULL; - } -} - -static struct video_device *cx23885_video_dev_alloc( - struct cx23885_tsport *tsport, - struct pci_dev *pci, - struct video_device *template, - char *type) -{ - struct video_device *vfd; - struct cx23885_dev *dev = tsport->dev; - - dprintk(1, "%s()\n", __func__); - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - *vfd = *template; - vfd->minor = -1; - snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, - type, cx23885_boards[tsport->dev->board].name); - vfd->parent = &pci->dev; - vfd->release = video_device_release; - return vfd; -} - -int cx23885_417_register(struct cx23885_dev *dev) -{ - /* FIXME: Port1 hardcoded here */ - int err = -ENODEV; - struct cx23885_tsport *tsport = &dev->ts1; - - dprintk(1, "%s()\n", __func__); - - if (cx23885_boards[dev->board].portb != CX23885_MPEG_ENCODER) - return err; - - /* Set default TV standard */ - dev->encodernorm = cx23885_tvnorms[0]; - - if (dev->encodernorm.id & V4L2_STD_525_60) - tsport->height = 480; - else - tsport->height = 576; - - tsport->width = 720; - cx2341x_fill_defaults(&dev->mpeg_params); - - dev->mpeg_params.port = CX2341X_PORT_SERIAL; - - /* Allocate and initialize V4L video device */ - dev->v4l_device = cx23885_video_dev_alloc(tsport, - dev->pci, &cx23885_mpeg_template, "mpeg"); - err = video_register_device(dev->v4l_device, - VFL_TYPE_GRABBER, -1); - if (err < 0) { - printk(KERN_INFO "%s: can't register mpeg device\n", dev->name); - return err; - } - - /* Initialize MC417 registers */ - cx23885_mc417_init(dev); - - printk(KERN_INFO "%s: registered device video%d [mpeg]\n", - dev->name, dev->v4l_device->num); - - return 0; -} diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c deleted file mode 100644 index caa098beeec..00000000000 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 Steven Toth <stoth@linuxtv.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/init.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <media/cx25840.h> - -#include "cx23885.h" -#include "tuner-xc2028.h" - -/* ------------------------------------------------------------------ */ -/* board config info */ - -struct cx23885_board cx23885_boards[] = { - [CX23885_BOARD_UNKNOWN] = { - .name = "UNKNOWN/GENERIC", - /* Ensure safe default for unknown boards */ - .clk_freq = 0, - .input = {{ - .type = CX23885_VMUX_COMPOSITE1, - .vmux = 0, - }, { - .type = CX23885_VMUX_COMPOSITE2, - .vmux = 1, - }, { - .type = CX23885_VMUX_COMPOSITE3, - .vmux = 2, - }, { - .type = CX23885_VMUX_COMPOSITE4, - .vmux = 3, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = { - .name = "Hauppauge WinTV-HVR1800lp", - .portc = CX23885_MPEG_DVB, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0xff00, - }, { - .type = CX23885_VMUX_DEBUG, - .vmux = 0, - .gpio0 = 0xff01, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0xff02, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0xff02, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1800] = { - .name = "Hauppauge WinTV-HVR1800", - .porta = CX23885_ANALOG_VIDEO, - .portb = CX23885_MPEG_ENCODER, - .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_PHILIPS_TDA8290, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN6_CH1, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .gpio0 = 0, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1250] = { - .name = "Hauppauge WinTV-HVR1250", - .portc = CX23885_MPEG_DVB, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0xff00, - }, { - .type = CX23885_VMUX_DEBUG, - .vmux = 0, - .gpio0 = 0xff01, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0xff02, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0xff02, - } }, - }, - [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { - .name = "DViCO FusionHDTV5 Express", - .portb = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1500Q] = { - .name = "Hauppauge WinTV-HVR1500Q", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1500] = { - .name = "Hauppauge WinTV-HVR1500", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1200] = { - .name = "Hauppauge WinTV-HVR1200", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1700] = { - .name = "Hauppauge WinTV-HVR1700", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1400] = { - .name = "Hauppauge WinTV-HVR1400", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = { - .name = "DViCO FusionHDTV7 Dual Express", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP] = { - .name = "DViCO FusionHDTV DVB-T Dual Express", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H] = { - .name = "Leadtek Winfast PxDVR3200 H", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_COMPRO_VIDEOMATE_E650F] = { - .name = "Compro VideoMate E650F", - .portc = CX23885_MPEG_DVB, - }, -}; -const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); - -/* ------------------------------------------------------------------ */ -/* PCI subsystem IDs */ - -struct cx23885_subid cx23885_subids[] = { - { - .subvendor = 0x0070, - .subdevice = 0x3400, - .card = CX23885_BOARD_UNKNOWN, - }, { - .subvendor = 0x0070, - .subdevice = 0x7600, - .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp, - }, { - .subvendor = 0x0070, - .subdevice = 0x7800, - .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { - .subvendor = 0x0070, - .subdevice = 0x7801, - .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { - .subvendor = 0x0070, - .subdevice = 0x7809, - .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { - .subvendor = 0x0070, - .subdevice = 0x7911, - .card = CX23885_BOARD_HAUPPAUGE_HVR1250, - }, { - .subvendor = 0x18ac, - .subdevice = 0xd500, - .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, - }, { - .subvendor = 0x0070, - .subdevice = 0x7790, - .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, - }, { - .subvendor = 0x0070, - .subdevice = 0x7797, - .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, - }, { - .subvendor = 0x0070, - .subdevice = 0x7710, - .card = CX23885_BOARD_HAUPPAUGE_HVR1500, - }, { - .subvendor = 0x0070, - .subdevice = 0x7717, - .card = CX23885_BOARD_HAUPPAUGE_HVR1500, - }, { - .subvendor = 0x0070, - .subdevice = 0x71d1, - .card = CX23885_BOARD_HAUPPAUGE_HVR1200, - }, { - .subvendor = 0x0070, - .subdevice = 0x71d3, - .card = CX23885_BOARD_HAUPPAUGE_HVR1200, - }, { - .subvendor = 0x0070, - .subdevice = 0x8101, - .card = CX23885_BOARD_HAUPPAUGE_HVR1700, - }, { - .subvendor = 0x0070, - .subdevice = 0x8010, - .card = CX23885_BOARD_HAUPPAUGE_HVR1400, - }, { - .subvendor = 0x18ac, - .subdevice = 0xd618, - .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, - }, { - .subvendor = 0x18ac, - .subdevice = 0xdb78, - .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP, - }, { - .subvendor = 0x107d, - .subdevice = 0x6681, - .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H, - }, { - .subvendor = 0x185b, - .subdevice = 0xe800, - .card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F, - }, -}; -const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); - -void cx23885_card_list(struct cx23885_dev *dev) -{ - int i; - - if (0 == dev->pci->subsystem_vendor && - 0 == dev->pci->subsystem_device) { - printk(KERN_INFO - "%s: Board has no valid PCIe Subsystem ID and can't\n" - "%s: be autodetected. Pass card=<n> insmod option\n" - "%s: to workaround that. Redirect complaints to the\n" - "%s: vendor of the TV card. Best regards,\n" - "%s: -- tux\n", - dev->name, dev->name, dev->name, dev->name, dev->name); - } else { - printk(KERN_INFO - "%s: Your board isn't known (yet) to the driver.\n" - "%s: Try to pick one of the existing card configs via\n" - "%s: card=<n> insmod option. Updating to the latest\n" - "%s: version might help as well.\n", - dev->name, dev->name, dev->name, dev->name); - } - printk(KERN_INFO "%s: Here is a list of valid choices for the card=<n> insmod option:\n", - dev->name); - for (i = 0; i < cx23885_bcount; i++) - printk(KERN_INFO "%s: card=%d -> %s\n", - dev->name, i, cx23885_boards[i].name); -} - -static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) -{ - struct tveeprom tv; - - tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, - eeprom_data); - - /* Make sure we support the board model */ - switch (tv.model) { - case 71009: - /* WinTV-HVR1200 (PCIe, Retail, full height) - * DVB-T and basic analog */ - case 71359: - /* WinTV-HVR1200 (PCIe, OEM, half height) - * DVB-T and basic analog */ - case 71439: - /* WinTV-HVR1200 (PCIe, OEM, half height) - * DVB-T and basic analog */ - case 71449: - /* WinTV-HVR1200 (PCIe, OEM, full height) - * DVB-T and basic analog */ - case 71939: - /* WinTV-HVR1200 (PCIe, OEM, half height) - * DVB-T and basic analog */ - case 71949: - /* WinTV-HVR1200 (PCIe, OEM, full height) - * DVB-T and basic analog */ - case 71959: - /* WinTV-HVR1200 (PCIe, OEM, full height) - * DVB-T and basic analog */ - case 71979: - /* WinTV-HVR1200 (PCIe, OEM, half height) - * DVB-T and basic analog */ - case 71999: - /* WinTV-HVR1200 (PCIe, OEM, full height) - * DVB-T and basic analog */ - case 76601: - /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual - channel ATSC and MPEG2 HW Encoder */ - case 77001: - /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC - and Basic analog */ - case 77011: - /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC - and Basic analog */ - case 77041: - /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM - and Basic analog */ - case 77051: - /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM - and Basic analog */ - case 78011: - /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78501: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78521: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78531: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78631: - /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 79001: - /* WinTV-HVR1250 (PCIe, Retail, IR, full height, - ATSC and Basic analog */ - case 79101: - /* WinTV-HVR1250 (PCIe, Retail, IR, half height, - ATSC and Basic analog */ - case 79561: - /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, - ATSC and Basic analog */ - case 79571: - /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, - ATSC and Basic analog */ - case 79671: - /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, - ATSC and Basic analog */ - case 80019: - /* WinTV-HVR1400 (Express Card, Retail, IR, - * DVB-T and Basic analog */ - case 81509: - /* WinTV-HVR1700 (PCIe, OEM, No IR, half height) - * DVB-T and MPEG2 HW Encoder */ - case 81519: - /* WinTV-HVR1700 (PCIe, OEM, No IR, full height) - * DVB-T and MPEG2 HW Encoder */ - break; - default: - printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n", - dev->name, tv.model); - break; - } - - printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", - dev->name, tv.model); -} - -int cx23885_tuner_callback(void *priv, int component, int command, int arg) -{ - struct cx23885_tsport *port = priv; - struct cx23885_dev *dev = port->dev; - u32 bitmask = 0; - - if (command == XC2028_RESET_CLK) - return 0; - - if (command != 0) { - printk(KERN_ERR "%s(): Unknown command 0x%x.\n", - __func__, command); - return -EINVAL; - } - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1400: - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - /* Tuner Reset Command */ - bitmask = 0x04; - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - /* Two identical tuners on two different i2c buses, - * we need to reset the correct gpio. */ - if (port->nr == 0) - bitmask = 0x01; - else if (port->nr == 1) - bitmask = 0x04; - break; - } - - if (bitmask) { - /* Drive the tuner into reset and back out */ - cx_clear(GP0_IO, bitmask); - mdelay(200); - cx_set(GP0_IO, bitmask); - } - - return 0; -} - -void cx23885_gpio_setup(struct cx23885_dev *dev) -{ - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - /* GPIO-0 cx24227 demodulator reset */ - cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500: - /* GPIO-0 cx24227 demodulator */ - /* GPIO-2 xc3028 tuner */ - - /* Put the parts into reset */ - cx_set(GP0_IO, 0x00050000); - cx_clear(GP0_IO, 0x00000005); - msleep(5); - - /* Bring the parts out of reset */ - cx_set(GP0_IO, 0x00050005); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - /* GPIO-0 cx24227 demodulator reset */ - /* GPIO-2 xc5000 tuner reset */ - cx_set(GP0_IO, 0x00050005); /* Bring the part out of reset */ - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800: - /* GPIO-0 656_CLK */ - /* GPIO-1 656_D0 */ - /* GPIO-2 8295A Reset */ - /* GPIO-3-10 cx23417 data0-7 */ - /* GPIO-11-14 cx23417 addr0-3 */ - /* GPIO-15-18 cx23417 READY, CS, RD, WR */ - /* GPIO-19 IR_RX */ - - /* CX23417 GPIO's */ - /* EIO15 Zilog Reset */ - /* EIO14 S5H1409/CX24227 Reset */ - - /* Force the TDA8295A into reset and back */ - cx_set(GP0_IO, 0x00040004); - mdelay(20); - cx_clear(GP0_IO, 0x00000004); - mdelay(20); - cx_set(GP0_IO, 0x00040004); - mdelay(20); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1200: - /* GPIO-0 tda10048 demodulator reset */ - /* GPIO-2 tda18271 tuner reset */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00050000); - mdelay(20); - cx_clear(GP0_IO, 0x00000005); - mdelay(20); - cx_set(GP0_IO, 0x00050005); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1700: - /* GPIO-0 TDA10048 demodulator reset */ - /* GPIO-2 TDA8295A Reset */ - /* GPIO-3-10 cx23417 data0-7 */ - /* GPIO-11-14 cx23417 addr0-3 */ - /* GPIO-15-18 cx23417 READY, CS, RD, WR */ - - /* The following GPIO's are on the interna AVCore (cx25840) */ - /* GPIO-19 IR_RX */ - /* GPIO-20 IR_TX 416/DVBT Select */ - /* GPIO-21 IIS DAT */ - /* GPIO-22 IIS WCLK */ - /* GPIO-23 IIS BCLK */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00050000); - mdelay(20); - cx_clear(GP0_IO, 0x00000005); - mdelay(20); - cx_set(GP0_IO, 0x00050005); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1400: - /* GPIO-0 Dibcom7000p demodulator reset */ - /* GPIO-2 xc3028L tuner reset */ - /* GPIO-13 LED */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00050000); - mdelay(20); - cx_clear(GP0_IO, 0x00000005); - mdelay(20); - cx_set(GP0_IO, 0x00050005); - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - /* GPIO-0 xc5000 tuner reset i2c bus 0 */ - /* GPIO-1 s5h1409 demod reset i2c bus 0 */ - /* GPIO-2 xc5000 tuner reset i2c bus 1 */ - /* GPIO-3 s5h1409 demod reset i2c bus 0 */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x000f0000); - mdelay(20); - cx_clear(GP0_IO, 0x0000000f); - mdelay(20); - cx_set(GP0_IO, 0x000f000f); - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - /* GPIO-0 portb xc3028 reset */ - /* GPIO-1 portb zl10353 reset */ - /* GPIO-2 portc xc3028 reset */ - /* GPIO-3 portc zl10353 reset */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x000f0000); - mdelay(20); - cx_clear(GP0_IO, 0x0000000f); - mdelay(20); - cx_set(GP0_IO, 0x000f000f); - break; - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - /* GPIO-2 xc3028 tuner reset */ - - /* The following GPIO's are on the internal AVCore (cx25840) */ - /* GPIO-? zl10353 demod reset */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00040000); - mdelay(20); - cx_clear(GP0_IO, 0x00000004); - mdelay(20); - cx_set(GP0_IO, 0x00040004); - break; - } -} - -int cx23885_ir_init(struct cx23885_dev *dev) -{ - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_HAUPPAUGE_HVR1800: - case CX23885_BOARD_HAUPPAUGE_HVR1200: - case CX23885_BOARD_HAUPPAUGE_HVR1400: - /* FIXME: Implement me */ - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - request_module("ir-kbd-i2c"); - break; - } - - return 0; -} - -void cx23885_card_setup(struct cx23885_dev *dev) -{ - struct cx23885_tsport *ts1 = &dev->ts1; - struct cx23885_tsport *ts2 = &dev->ts2; - - static u8 eeprom[256]; - - if (dev->i2c_bus[0].i2c_rc == 0) { - dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; - tveeprom_read(&dev->i2c_bus[0].i2c_client, - eeprom, sizeof(eeprom)); - } - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_HAUPPAUGE_HVR1400: - if (dev->i2c_bus[0].i2c_rc == 0) - hauppauge_eeprom(dev, eeprom+0x80); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800: - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - case CX23885_BOARD_HAUPPAUGE_HVR1200: - case CX23885_BOARD_HAUPPAUGE_HVR1700: - if (dev->i2c_bus[0].i2c_rc == 0) - hauppauge_eeprom(dev, eeprom+0xc0); - break; - } - - switch (dev->board) { - case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - /* break omitted intentionally */ - case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: - ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800: - /* Defaults for VID B - Analog encoder */ - /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */ - ts1->gen_ctrl_val = 0x10e; - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - - /* APB_TSVALERR_POL (active low)*/ - ts1->vld_misc_val = 0x2000; - ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc); - - /* Defaults for VID C */ - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_HAUPPAUGE_HVR1250: - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - case CX23885_BOARD_HAUPPAUGE_HVR1200: - case CX23885_BOARD_HAUPPAUGE_HVR1700: - case CX23885_BOARD_HAUPPAUGE_HVR1400: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - default: - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - } - - /* Certain boards support analog, or require the avcore to be - * loaded, ensure this happens. - */ - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1800: - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - case CX23885_BOARD_HAUPPAUGE_HVR1700: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - request_module("cx25840"); - break; - } -} - -/* ------------------------------------------------------------------ */ diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c deleted file mode 100644 index 8f6fb2add7d..00000000000 --- a/drivers/media/video/cx23885/cx23885-core.c +++ /dev/null @@ -1,1841 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 Steven Toth <stoth@linuxtv.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/init.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kmod.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <asm/div64.h> - -#include "cx23885.h" - -MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); -MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); -MODULE_LICENSE("GPL"); - -static unsigned int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debug messages"); - -static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; -module_param_array(card, int, NULL, 0444); -MODULE_PARM_DESC(card, "card type"); - -#define dprintk(level, fmt, arg...)\ - do { if (debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ - } while (0) - -static unsigned int cx23885_devcount; - -static DEFINE_MUTEX(devlist); -LIST_HEAD(cx23885_devlist); - -#define NO_SYNC_LINE (-1U) - -/* FIXME, these allocations will change when - * analog arrives. The be reviewed. - * CX23887 Assumptions - * 1 line = 16 bytes of CDT - * cmds size = 80 - * cdt size = 16 * linesize - * iqsize = 64 - * maxlines = 6 - * - * Address Space: - * 0x00000000 0x00008fff FIFO clusters - * 0x00010000 0x000104af Channel Management Data Structures - * 0x000104b0 0x000104ff Free - * 0x00010500 0x000108bf 15 channels * iqsize - * 0x000108c0 0x000108ff Free - * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables - * 15 channels * (iqsize + (maxlines * linesize)) - * 0x00010ea0 0x00010xxx Free - */ - -static struct sram_channel cx23885_sram_channels[] = { - [SRAM_CH01] = { - .name = "VID A", - .cmds_start = 0x10000, - .ctrl_start = 0x10380, - .cdt = 0x104c0, - .fifo_start = 0x40, - .fifo_size = 0x2800, - .ptr1_reg = DMA1_PTR1, - .ptr2_reg = DMA1_PTR2, - .cnt1_reg = DMA1_CNT1, - .cnt2_reg = DMA1_CNT2, - }, - [SRAM_CH02] = { - .name = "ch2", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA2_PTR1, - .ptr2_reg = DMA2_PTR2, - .cnt1_reg = DMA2_CNT1, - .cnt2_reg = DMA2_CNT2, - }, - [SRAM_CH03] = { - .name = "TS1 B", - .cmds_start = 0x100A0, - .ctrl_start = 0x10400, - .cdt = 0x10580, - .fifo_start = 0x5000, - .fifo_size = 0x1000, - .ptr1_reg = DMA3_PTR1, - .ptr2_reg = DMA3_PTR2, - .cnt1_reg = DMA3_CNT1, - .cnt2_reg = DMA3_CNT2, - }, - [SRAM_CH04] = { - .name = "ch4", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA4_PTR1, - .ptr2_reg = DMA4_PTR2, - .cnt1_reg = DMA4_CNT1, - .cnt2_reg = DMA4_CNT2, - }, - [SRAM_CH05] = { - .name = "ch5", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA5_PTR1, - .ptr2_reg = DMA5_PTR2, - .cnt1_reg = DMA5_CNT1, - .cnt2_reg = DMA5_CNT2, - }, - [SRAM_CH06] = { - .name = "TS2 C", - .cmds_start = 0x10140, - .ctrl_start = 0x10440, - .cdt = 0x105e0, - .fifo_start = 0x6000, - .fifo_size = 0x1000, - .ptr1_reg = DMA5_PTR1, - .ptr2_reg = DMA5_PTR2, - .cnt1_reg = DMA5_CNT1, - .cnt2_reg = DMA5_CNT2, - }, - [SRAM_CH07] = { - .name = "ch7", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA6_PTR1, - .ptr2_reg = DMA6_PTR2, - .cnt1_reg = DMA6_CNT1, - .cnt2_reg = DMA6_CNT2, - }, - [SRAM_CH08] = { - .name = "ch8", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA7_PTR1, - .ptr2_reg = DMA7_PTR2, - .cnt1_reg = DMA7_CNT1, - .cnt2_reg = DMA7_CNT2, - }, - [SRAM_CH09] = { - .name = "ch9", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA8_PTR1, - .ptr2_reg = DMA8_PTR2, - .cnt1_reg = DMA8_CNT1, - .cnt2_reg = DMA8_CNT2, - }, -}; - -static struct sram_channel cx23887_sram_channels[] = { - [SRAM_CH01] = { - .name = "VID A", - .cmds_start = 0x10000, - .ctrl_start = 0x105b0, - .cdt = 0x107b0, - .fifo_start = 0x40, - .fifo_size = 0x2800, - .ptr1_reg = DMA1_PTR1, - .ptr2_reg = DMA1_PTR2, - .cnt1_reg = DMA1_CNT1, - .cnt2_reg = DMA1_CNT2, - }, - [SRAM_CH02] = { - .name = "ch2", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA2_PTR1, - .ptr2_reg = DMA2_PTR2, - .cnt1_reg = DMA2_CNT1, - .cnt2_reg = DMA2_CNT2, - }, - [SRAM_CH03] = { - .name = "TS1 B", - .cmds_start = 0x100A0, - .ctrl_start = 0x10630, - .cdt = 0x10870, - .fifo_start = 0x5000, - .fifo_size = 0x1000, - .ptr1_reg = DMA3_PTR1, - .ptr2_reg = DMA3_PTR2, - .cnt1_reg = DMA3_CNT1, - .cnt2_reg = DMA3_CNT2, - }, - [SRAM_CH04] = { - .name = "ch4", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA4_PTR1, - .ptr2_reg = DMA4_PTR2, - .cnt1_reg = DMA4_CNT1, - .cnt2_reg = DMA4_CNT2, - }, - [SRAM_CH05] = { - .name = "ch5", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA5_PTR1, - .ptr2_reg = DMA5_PTR2, - .cnt1_reg = DMA5_CNT1, - .cnt2_reg = DMA5_CNT2, - }, - [SRAM_CH06] = { - .name = "TS2 C", - .cmds_start = 0x10140, - .ctrl_start = 0x10670, - .cdt = 0x108d0, - .fifo_start = 0x6000, - .fifo_size = 0x1000, - .ptr1_reg = DMA5_PTR1, - .ptr2_reg = DMA5_PTR2, - .cnt1_reg = DMA5_CNT1, - .cnt2_reg = DMA5_CNT2, - }, - [SRAM_CH07] = { - .name = "ch7", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA6_PTR1, - .ptr2_reg = DMA6_PTR2, - .cnt1_reg = DMA6_CNT1, - .cnt2_reg = DMA6_CNT2, - }, - [SRAM_CH08] = { - .name = "ch8", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA7_PTR1, - .ptr2_reg = DMA7_PTR2, - .cnt1_reg = DMA7_CNT1, - .cnt2_reg = DMA7_CNT2, - }, - [SRAM_CH09] = { - .name = "ch9", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA8_PTR1, - .ptr2_reg = DMA8_PTR2, - .cnt1_reg = DMA8_CNT1, - .cnt2_reg = DMA8_CNT2, - }, -}; - -static int cx23885_risc_decode(u32 risc) -{ - static char *instr[16] = { - [RISC_SYNC >> 28] = "sync", - [RISC_WRITE >> 28] = "write", - [RISC_WRITEC >> 28] = "writec", - [RISC_READ >> 28] = "read", - [RISC_READC >> 28] = "readc", - [RISC_JUMP >> 28] = "jump", - [RISC_SKIP >> 28] = "skip", - [RISC_WRITERM >> 28] = "writerm", - [RISC_WRITECM >> 28] = "writecm", - [RISC_WRITECR >> 28] = "writecr", - }; - static int incr[16] = { - [RISC_WRITE >> 28] = 3, - [RISC_JUMP >> 28] = 3, - [RISC_SKIP >> 28] = 1, - [RISC_SYNC >> 28] = 1, - [RISC_WRITERM >> 28] = 3, - [RISC_WRITECM >> 28] = 3, - [RISC_WRITECR >> 28] = 4, - }; - static char *bits[] = { - "12", "13", "14", "resync", - "cnt0", "cnt1", "18", "19", - "20", "21", "22", "23", - "irq1", "irq2", "eol", "sol", - }; - int i; - - printk("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))) - printk(" %s", bits[i]); - printk(" count=%d ]\n", risc & 0xfff); - return incr[risc >> 28] ? incr[risc >> 28] : 1; -} - -void cx23885_wakeup(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q, u32 count) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_buffer *buf; - int bc; - - for (bc = 0;; bc++) { - if (list_empty(&q->active)) - break; - buf = list_entry(q->active.next, - struct cx23885_buffer, vb.queue); - - /* count comes from the hw and is is 16bit wide -- - * this trick handles wrap-arounds correctly for - * up to 32767 buffers in flight... */ - if ((s16) (count - buf->count) < 0) - break; - - do_gettimeofday(&buf->vb.ts); - dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, - count, buf->count); - buf->vb.state = VIDEOBUF_DONE; - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); - } - if (list_empty(&q->active)) - del_timer(&q->timeout); - else - mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); - if (bc != 1) - printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n", - __func__, bc); -} - -int cx23885_sram_channel_setup(struct cx23885_dev *dev, - struct sram_channel *ch, - unsigned int bpl, u32 risc) -{ - unsigned int i, lines; - u32 cdt; - - if (ch->cmds_start == 0) { - dprintk(1, "%s() Erasing channel [%s]\n", __func__, - ch->name); - cx_write(ch->ptr1_reg, 0); - cx_write(ch->ptr2_reg, 0); - cx_write(ch->cnt2_reg, 0); - cx_write(ch->cnt1_reg, 0); - return 0; - } else { - dprintk(1, "%s() Configuring channel [%s]\n", __func__, - ch->name); - } - - bpl = (bpl + 7) & ~7; /* alignment */ - cdt = ch->cdt; - lines = ch->fifo_size / bpl; - if (lines > 6) - lines = 6; - BUG_ON(lines < 2); - - cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - cx_write(8 + 4, 8); - cx_write(8 + 8, 0); - - /* write CDT */ - for (i = 0; i < lines; i++) { - dprintk(2, "%s() 0x%08x <- 0x%08x\n", __func__, cdt + 16*i, - ch->fifo_start + bpl*i); - cx_write(cdt + 16*i, ch->fifo_start + bpl*i); - cx_write(cdt + 16*i + 4, 0); - cx_write(cdt + 16*i + 8, 0); - cx_write(cdt + 16*i + 12, 0); - } - - /* write CMDS */ - if (ch->jumponly) - cx_write(ch->cmds_start + 0, 8); - else - cx_write(ch->cmds_start + 0, risc); - cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ - cx_write(ch->cmds_start + 8, cdt); - cx_write(ch->cmds_start + 12, (lines*16) >> 3); - cx_write(ch->cmds_start + 16, ch->ctrl_start); - if (ch->jumponly) - cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2)); - else - cx_write(ch->cmds_start + 20, 64 >> 2); - for (i = 24; i < 80; i += 4) - cx_write(ch->cmds_start + i, 0); - - /* fill registers */ - cx_write(ch->ptr1_reg, ch->fifo_start); - cx_write(ch->ptr2_reg, cdt); - cx_write(ch->cnt2_reg, (lines*16) >> 3); - cx_write(ch->cnt1_reg, (bpl >> 3) - 1); - - dprintk(2, "[bridge %d] sram setup %s: bpl=%d lines=%d\n", - dev->bridge, - ch->name, - bpl, - lines); - - return 0; -} - -void cx23885_sram_channel_dump(struct cx23885_dev *dev, - struct sram_channel *ch) -{ - static char *name[] = { - "init risc lo", - "init risc hi", - "cdt base", - "cdt size", - "iq base", - "iq size", - "risc pc lo", - "risc pc hi", - "iq wr ptr", - "iq rd ptr", - "cdt current", - "pci target lo", - "pci target hi", - "line / byte", - }; - u32 risc; - unsigned int i, j, n; - - printk(KERN_WARNING "%s: %s - dma channel status dump\n", - dev->name, ch->name); - for (i = 0; i < ARRAY_SIZE(name); i++) - printk(KERN_WARNING "%s: cmds: %-15s: 0x%08x\n", - dev->name, name[i], - cx_read(ch->cmds_start + 4*i)); - - for (i = 0; i < 4; i++) { - risc = cx_read(ch->cmds_start + 4 * (i + 14)); - printk(KERN_WARNING "%s: risc%d: ", dev->name, i); - cx23885_risc_decode(risc); - } - for (i = 0; i < (64 >> 2); i += n) { - risc = cx_read(ch->ctrl_start + 4 * i); - /* No consideration for bits 63-32 */ - - printk(KERN_WARNING "%s: (0x%08x) iq %x: ", dev->name, - ch->ctrl_start + 4 * i, i); - n = cx23885_risc_decode(risc); - for (j = 1; j < n; j++) { - risc = cx_read(ch->ctrl_start + 4 * (i + j)); - printk(KERN_WARNING "%s: iq %x: 0x%08x [ arg #%d ]\n", - dev->name, i+j, risc, j); - } - } - - printk(KERN_WARNING "%s: fifo: 0x%08x -> 0x%x\n", - dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); - printk(KERN_WARNING "%s: ctrl: 0x%08x -> 0x%x\n", - dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); - printk(KERN_WARNING "%s: ptr1_reg: 0x%08x\n", - dev->name, cx_read(ch->ptr1_reg)); - printk(KERN_WARNING "%s: ptr2_reg: 0x%08x\n", - dev->name, cx_read(ch->ptr2_reg)); - printk(KERN_WARNING "%s: cnt1_reg: 0x%08x\n", - dev->name, cx_read(ch->cnt1_reg)); - printk(KERN_WARNING "%s: cnt2_reg: 0x%08x\n", - dev->name, cx_read(ch->cnt2_reg)); -} - -static void cx23885_risc_disasm(struct cx23885_tsport *port, - struct btcx_riscmem *risc) -{ - struct cx23885_dev *dev = port->dev; - unsigned int i, j, n; - - printk(KERN_INFO "%s: risc disasm: %p [dma=0x%08lx]\n", - dev->name, risc->cpu, (unsigned long)risc->dma); - for (i = 0; i < (risc->size >> 2); i += n) { - printk(KERN_INFO "%s: %04d: ", dev->name, i); - n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i])); - for (j = 1; j < n; j++) - printk(KERN_INFO "%s: %04d: 0x%08x [ arg #%d ]\n", - dev->name, i + j, risc->cpu[i + j], j); - if (risc->cpu[i] == cpu_to_le32(RISC_JUMP)) - break; - } -} - -static void cx23885_shutdown(struct cx23885_dev *dev) -{ - /* disable RISC controller */ - cx_write(DEV_CNTRL2, 0); - - /* Disable all IR activity */ - cx_write(IR_CNTRL_REG, 0); - - /* Disable Video A/B activity */ - cx_write(VID_A_DMA_CTL, 0); - cx_write(VID_B_DMA_CTL, 0); - cx_write(VID_C_DMA_CTL, 0); - - /* Disable Audio activity */ - cx_write(AUD_INT_DMA_CTL, 0); - cx_write(AUD_EXT_DMA_CTL, 0); - - /* Disable Serial port */ - cx_write(UART_CTL, 0); - - /* Disable Interrupts */ - cx_write(PCI_INT_MSK, 0); - cx_write(VID_A_INT_MSK, 0); - cx_write(VID_B_INT_MSK, 0); - cx_write(VID_C_INT_MSK, 0); - cx_write(AUDIO_INT_INT_MSK, 0); - cx_write(AUDIO_EXT_INT_MSK, 0); - -} - -static void cx23885_reset(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - cx23885_shutdown(dev); - - cx_write(PCI_INT_STAT, 0xffffffff); - cx_write(VID_A_INT_STAT, 0xffffffff); - cx_write(VID_B_INT_STAT, 0xffffffff); - cx_write(VID_C_INT_STAT, 0xffffffff); - cx_write(AUDIO_INT_INT_STAT, 0xffffffff); - cx_write(AUDIO_EXT_INT_STAT, 0xffffffff); - cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); - cx_write(PAD_CTRL, 0x00500300); - - mdelay(100); - - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], - 720*4, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH03], - 188*4, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH04], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH05], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH06], - 188*4, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH07], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH08], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH09], 128, 0); - - cx23885_gpio_setup(dev); -} - - -static int cx23885_pci_quirks(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - /* The cx23885 bridge has a weird bug which causes NMI to be asserted - * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not - * occur on the cx23887 bridge. - */ - if (dev->bridge == CX23885_BRIDGE_885) - cx_clear(RDR_TLCTL0, 1 << 4); - - return 0; -} - -static int get_resources(struct cx23885_dev *dev) -{ - if (request_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0), - dev->name)) - return 0; - - printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", - dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); - - return -EBUSY; -} - -static void cx23885_timeout(unsigned long data); -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, - u32 reg, u32 mask, u32 value); - -static int cx23885_init_tsport(struct cx23885_dev *dev, - struct cx23885_tsport *port, int portno) -{ - dprintk(1, "%s(portno=%d)\n", __func__, portno); - - /* Transport bus init dma queue - Common settings */ - port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ - port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */ - port->vld_misc_val = 0x0; - port->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4); - - spin_lock_init(&port->slock); - port->dev = dev; - port->nr = portno; - - INIT_LIST_HEAD(&port->mpegq.active); - INIT_LIST_HEAD(&port->mpegq.queued); - port->mpegq.timeout.function = cx23885_timeout; - port->mpegq.timeout.data = (unsigned long)port; - init_timer(&port->mpegq.timeout); - - mutex_init(&port->frontends.lock); - INIT_LIST_HEAD(&port->frontends.felist); - port->frontends.active_fe_id = 0; - - /* This should be hardcoded allow a single frontend - * attachment to this tsport, keeping the -dvb.c - * code clean and safe. - */ - if (!port->num_frontends) - port->num_frontends = 1; - - switch (portno) { - case 1: - port->reg_gpcnt = VID_B_GPCNT; - port->reg_gpcnt_ctl = VID_B_GPCNT_CTL; - port->reg_dma_ctl = VID_B_DMA_CTL; - port->reg_lngth = VID_B_LNGTH; - port->reg_hw_sop_ctrl = VID_B_HW_SOP_CTL; - port->reg_gen_ctrl = VID_B_GEN_CTL; - port->reg_bd_pkt_status = VID_B_BD_PKT_STATUS; - port->reg_sop_status = VID_B_SOP_STATUS; - port->reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT; - port->reg_vld_misc = VID_B_VLD_MISC; - port->reg_ts_clk_en = VID_B_TS_CLK_EN; - port->reg_src_sel = VID_B_SRC_SEL; - port->reg_ts_int_msk = VID_B_INT_MSK; - port->reg_ts_int_stat = VID_B_INT_STAT; - port->sram_chno = SRAM_CH03; /* VID_B */ - port->pci_irqmask = 0x02; /* VID_B bit1 */ - break; - case 2: - port->reg_gpcnt = VID_C_GPCNT; - port->reg_gpcnt_ctl = VID_C_GPCNT_CTL; - port->reg_dma_ctl = VID_C_DMA_CTL; - port->reg_lngth = VID_C_LNGTH; - port->reg_hw_sop_ctrl = VID_C_HW_SOP_CTL; - port->reg_gen_ctrl = VID_C_GEN_CTL; - port->reg_bd_pkt_status = VID_C_BD_PKT_STATUS; - port->reg_sop_status = VID_C_SOP_STATUS; - port->reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT; - port->reg_vld_misc = VID_C_VLD_MISC; - port->reg_ts_clk_en = VID_C_TS_CLK_EN; - port->reg_src_sel = 0; - port->reg_ts_int_msk = VID_C_INT_MSK; - port->reg_ts_int_stat = VID_C_INT_STAT; - port->sram_chno = SRAM_CH06; /* VID_C */ - port->pci_irqmask = 0x04; /* VID_C bit2 */ - break; - default: - BUG(); - } - - cx23885_risc_stopper(dev->pci, &port->mpegq.stopper, - port->reg_dma_ctl, port->dma_ctl_val, 0x00); - - return 0; -} - -static void cx23885_dev_checkrevision(struct cx23885_dev *dev) -{ - switch (cx_read(RDR_CFG2) & 0xff) { - case 0x00: - /* cx23885 */ - dev->hwrevision = 0xa0; - break; - case 0x01: - /* CX23885-12Z */ - dev->hwrevision = 0xa1; - break; - case 0x02: - /* CX23885-13Z */ - dev->hwrevision = 0xb0; - break; - case 0x03: - /* CX23888-22Z */ - dev->hwrevision = 0xc0; - break; - case 0x0e: - /* CX23887-15Z */ - dev->hwrevision = 0xc0; - case 0x0f: - /* CX23887-14Z */ - dev->hwrevision = 0xb1; - break; - default: - printk(KERN_ERR "%s() New hardware revision found 0x%x\n", - __func__, dev->hwrevision); - } - if (dev->hwrevision) - printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", - __func__, dev->hwrevision); - else - printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n", - __func__, dev->hwrevision); -} - -static int cx23885_dev_setup(struct cx23885_dev *dev) -{ - int i; - - mutex_init(&dev->lock); - - atomic_inc(&dev->refcount); - - dev->nr = cx23885_devcount++; - sprintf(dev->name, "cx23885[%d]", dev->nr); - - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &cx23885_devlist); - mutex_unlock(&devlist); - - /* Configure the internal memory */ - if (dev->pci->device == 0x8880) { - dev->bridge = CX23885_BRIDGE_887; - /* Apply a sensible clock frequency for the PCIe bridge */ - dev->clk_freq = 25000000; - dev->sram_channels = cx23887_sram_channels; - } else - if (dev->pci->device == 0x8852) { - dev->bridge = CX23885_BRIDGE_885; - /* Apply a sensible clock frequency for the PCIe bridge */ - dev->clk_freq = 28000000; - dev->sram_channels = cx23885_sram_channels; - } else - BUG(); - - dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", - __func__, dev->bridge); - - /* board config */ - dev->board = UNSET; - if (card[dev->nr] < cx23885_bcount) - dev->board = card[dev->nr]; - for (i = 0; UNSET == dev->board && i < cx23885_idcount; i++) - if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor && - dev->pci->subsystem_device == cx23885_subids[i].subdevice) - dev->board = cx23885_subids[i].card; - if (UNSET == dev->board) { - dev->board = CX23885_BOARD_UNKNOWN; - cx23885_card_list(dev); - } - - /* If the user specific a clk freq override, apply it */ - if (cx23885_boards[dev->board].clk_freq > 0) - dev->clk_freq = cx23885_boards[dev->board].clk_freq; - - dev->pci_bus = dev->pci->bus->number; - dev->pci_slot = PCI_SLOT(dev->pci->devfn); - dev->pci_irqmask = 0x001f00; - - /* External Master 1 Bus */ - dev->i2c_bus[0].nr = 0; - dev->i2c_bus[0].dev = dev; - dev->i2c_bus[0].reg_stat = I2C1_STAT; - dev->i2c_bus[0].reg_ctrl = I2C1_CTRL; - dev->i2c_bus[0].reg_addr = I2C1_ADDR; - dev->i2c_bus[0].reg_rdata = I2C1_RDATA; - dev->i2c_bus[0].reg_wdata = I2C1_WDATA; - dev->i2c_bus[0].i2c_period = (0x9d << 24); /* 100kHz */ - - /* External Master 2 Bus */ - dev->i2c_bus[1].nr = 1; - dev->i2c_bus[1].dev = dev; - dev->i2c_bus[1].reg_stat = I2C2_STAT; - dev->i2c_bus[1].reg_ctrl = I2C2_CTRL; - dev->i2c_bus[1].reg_addr = I2C2_ADDR; - dev->i2c_bus[1].reg_rdata = I2C2_RDATA; - dev->i2c_bus[1].reg_wdata = I2C2_WDATA; - dev->i2c_bus[1].i2c_period = (0x9d << 24); /* 100kHz */ - - /* Internal Master 3 Bus */ - dev->i2c_bus[2].nr = 2; - dev->i2c_bus[2].dev = dev; - dev->i2c_bus[2].reg_stat = I2C3_STAT; - dev->i2c_bus[2].reg_ctrl = I2C3_CTRL; - dev->i2c_bus[2].reg_addr = I2C3_ADDR; - dev->i2c_bus[2].reg_rdata = I2C3_RDATA; - dev->i2c_bus[2].reg_wdata = I2C3_WDATA; - dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */ - - if ((cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) || - (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)) - cx23885_init_tsport(dev, &dev->ts1, 1); - - if ((cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) || - (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)) - cx23885_init_tsport(dev, &dev->ts2, 2); - - if (get_resources(dev) < 0) { - printk(KERN_ERR "CORE %s No more PCIe resources for " - "subsystem: %04x:%04x\n", - dev->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device); - - cx23885_devcount--; - return -ENODEV; - } - - /* PCIe stuff */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - dev->bmmio = (u8 __iomem *)dev->lmmio; - - printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", - dev->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device, cx23885_boards[dev->board].name, - dev->board, card[dev->nr] == dev->board ? - "insmod option" : "autodetected"); - - cx23885_pci_quirks(dev); - - /* Assume some sensible defaults */ - dev->tuner_type = cx23885_boards[dev->board].tuner_type; - dev->tuner_addr = cx23885_boards[dev->board].tuner_addr; - dev->radio_type = cx23885_boards[dev->board].radio_type; - dev->radio_addr = cx23885_boards[dev->board].radio_addr; - - dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n", - __func__, dev->tuner_type, dev->tuner_addr); - dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", - __func__, dev->radio_type, dev->radio_addr); - - /* init hardware */ - cx23885_reset(dev); - - cx23885_i2c_register(&dev->i2c_bus[0]); - cx23885_i2c_register(&dev->i2c_bus[1]); - cx23885_i2c_register(&dev->i2c_bus[2]); - cx23885_card_setup(dev); - cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); - cx23885_ir_init(dev); - - if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { - if (cx23885_video_register(dev) < 0) { - printk(KERN_ERR "%s() Failed to register analog " - "video adapters on VID_A\n", __func__); - } - } - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { - if (cx23885_dvb_register(&dev->ts1) < 0) { - printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", - __func__); - } - } else - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { - if (cx23885_417_register(dev) < 0) { - printk(KERN_ERR - "%s() Failed to register 417 on VID_B\n", - __func__); - } - } - - if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { - if (cx23885_dvb_register(&dev->ts2) < 0) { - printk(KERN_ERR - "%s() Failed to register dvb on VID_C\n", - __func__); - } - } else - if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) { - if (cx23885_417_register(dev) < 0) { - printk(KERN_ERR - "%s() Failed to register 417 on VID_C\n", - __func__); - } - } - - cx23885_dev_checkrevision(dev); - - return 0; -} - -static void cx23885_dev_unregister(struct cx23885_dev *dev) -{ - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - if (!atomic_dec_and_test(&dev->refcount)) - return; - - if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) - cx23885_video_unregister(dev); - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) - cx23885_dvb_unregister(&dev->ts1); - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - cx23885_417_unregister(dev); - - if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) - cx23885_dvb_unregister(&dev->ts2); - - if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) - cx23885_417_unregister(dev); - - cx23885_i2c_unregister(&dev->i2c_bus[2]); - cx23885_i2c_unregister(&dev->i2c_bus[1]); - cx23885_i2c_unregister(&dev->i2c_bus[0]); - - iounmap(dev->lmmio); -} - -static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, - unsigned int offset, u32 sync_line, - unsigned int bpl, unsigned int padding, - unsigned int lines) -{ - struct scatterlist *sg; - unsigned int line, todo; - - /* sync instruction */ - if (sync_line != NO_SYNC_LINE) - *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); - - /* scan lines */ - sg = sglist; - for (line = 0; line < lines; line++) { - 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(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); - *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - offset += bpl; - } else { - /* scanline needs to be split */ - todo = bpl; - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL| - (sg_dma_len(sg)-offset)); - *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - todo -= (sg_dma_len(sg)-offset); - offset = 0; - sg++; - while (todo > sg_dma_len(sg)) { - *(rp++) = cpu_to_le32(RISC_WRITE| - sg_dma_len(sg)); - *(rp++) = cpu_to_le32(sg_dma_address(sg)); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - todo -= sg_dma_len(sg); - sg++; - } - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo); - *(rp++) = cpu_to_le32(sg_dma_address(sg)); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - offset += todo; - } - offset += padding; - } - - return rp; -} - -int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, - struct scatterlist *sglist, unsigned int top_offset, - unsigned int bottom_offset, unsigned int bpl, - unsigned int padding, unsigned int lines) -{ - u32 instructions, fields; - __le32 *rp; - int rc; - - fields = 0; - if (UNSET != top_offset) - fields++; - if (UNSET != bottom_offset) - fields++; - - /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + 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 */ - /* write and jump need and extra dword */ - instructions = fields * (1 + ((bpl + padding) * lines) - / PAGE_SIZE + lines); - instructions += 2; - rc = btcx_riscmem_alloc(pci, risc, instructions*12); - if (rc < 0) - return rc; - - /* write risc instructions */ - rp = risc->cpu; - if (UNSET != top_offset) - rp = cx23885_risc_field(rp, sglist, top_offset, 0, - bpl, padding, lines); - if (UNSET != bottom_offset) - rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200, - bpl, padding, lines); - - /* 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 cx23885_risc_databuffer(struct pci_dev *pci, - struct btcx_riscmem *risc, - struct scatterlist *sglist, - unsigned int bpl, - unsigned int lines) -{ - u32 instructions; - __le32 *rp; - int rc; - - /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Here - there is no padding and no sync. First DMA region may be smaller - than PAGE_SIZE */ - /* Jump and write need an extra dword */ - instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; - instructions += 1; - - rc = btcx_riscmem_alloc(pci, risc, instructions*12); - if (rc < 0) - return rc; - - /* write risc instructions */ - rp = risc->cpu; - rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines); - - /* save pointer to jmp instruction address */ - risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); - return 0; -} - -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, - u32 reg, u32 mask, u32 value) -{ - __le32 *rp; - int rc; - - rc = btcx_riscmem_alloc(pci, risc, 4*16); - if (rc < 0) - return rc; - - /* write risc instructions */ - rp = risc->cpu; - *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2); - *(rp++) = cpu_to_le32(reg); - *(rp++) = cpu_to_le32(value); - *(rp++) = cpu_to_le32(mask); - *(rp++) = cpu_to_le32(RISC_JUMP); - *(rp++) = cpu_to_le32(risc->dma); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - return 0; -} - -void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) -{ - struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); - - BUG_ON(in_interrupt()); - videobuf_waiton(&buf->vb, 0, 0); - videobuf_dma_unmap(q, dma); - videobuf_dma_free(dma); - btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); - buf->vb.state = VIDEOBUF_NEEDS_INIT; -} - -static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) -{ - struct cx23885_dev *dev = port->dev; - - dprintk(1, "%s() Register Dump\n", __func__); - dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __func__, - cx_read(DEV_CNTRL2)); - dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __func__, - cx_read(PCI_INT_MSK)); - dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __func__, - cx_read(AUDIO_INT_INT_MSK)); - dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __func__, - cx_read(AUD_INT_DMA_CTL)); - dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __func__, - cx_read(AUDIO_EXT_INT_MSK)); - dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __func__, - cx_read(AUD_EXT_DMA_CTL)); - dprintk(1, "%s() PAD_CTRL 0x%08X\n", __func__, - cx_read(PAD_CTRL)); - dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __func__, - cx_read(ALT_PIN_OUT_SEL)); - dprintk(1, "%s() GPIO2 0x%08X\n", __func__, - cx_read(GPIO2)); - dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __func__, - port->reg_gpcnt, cx_read(port->reg_gpcnt)); - dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __func__, - port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); - dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__, - port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); - if (port->reg_src_sel) - dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, - port->reg_src_sel, cx_read(port->reg_src_sel)); - dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__, - port->reg_lngth, cx_read(port->reg_lngth)); - dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__, - port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl)); - dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __func__, - port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl)); - dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __func__, - port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status)); - dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __func__, - port->reg_sop_status, cx_read(port->reg_sop_status)); - dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __func__, - port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat)); - dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __func__, - port->reg_vld_misc, cx_read(port->reg_vld_misc)); - dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __func__, - port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en)); - dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __func__, - port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); -} - -static int cx23885_start_dma(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q, - struct cx23885_buffer *buf) -{ - struct cx23885_dev *dev = port->dev; - u32 reg; - - dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, - buf->vb.width, buf->vb.height, buf->vb.field); - - /* Stop the fifo and risc engine for this port */ - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - - /* setup fifo + format */ - cx23885_sram_channel_setup(dev, - &dev->sram_channels[port->sram_chno], - port->ts_packet_size, buf->risc.dma); - if (debug > 5) { - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); - cx23885_risc_disasm(port, &buf->risc); - } - - /* write TS length to chip */ - cx_write(port->reg_lngth, buf->vb.width); - - if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && - (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) { - printk("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n", - __func__, - cx23885_boards[dev->board].portb, - cx23885_boards[dev->board].portc); - return -EINVAL; - } - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - cx23885_av_clk(dev, 0); - - udelay(100); - - /* If the port supports SRC SELECT, configure it */ - if (port->reg_src_sel) - cx_write(port->reg_src_sel, port->src_sel_val); - - cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val); - cx_write(port->reg_ts_clk_en, port->ts_clk_en_val); - cx_write(port->reg_vld_misc, port->vld_misc_val); - cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); - udelay(100); - - /* NOTE: this is 2 (reserved) for portb, does it matter? */ - /* reset counter to zero */ - cx_write(port->reg_gpcnt_ctl, 3); - q->count = 1; - - /* Set VIDB pins to input */ - if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { - reg = cx_read(PAD_CTRL); - reg &= ~0x3; /* Clear TS1_OE & TS1_SOP_OE */ - cx_write(PAD_CTRL, reg); - } - - /* Set VIDC pins to input */ - if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { - reg = cx_read(PAD_CTRL); - reg &= ~0x4; /* Clear TS2_SOP_OE */ - cx_write(PAD_CTRL, reg); - } - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { - - reg = cx_read(PAD_CTRL); - reg = reg & ~0x1; /* Clear TS1_OE */ - - /* FIXME, bit 2 writing here is questionable */ - /* set TS1_SOP_OE and TS1_OE_HI */ - reg = reg | 0xa; - cx_write(PAD_CTRL, reg); - - /* FIXME and these two registers should be documented. */ - cx_write(CLK_DELAY, cx_read(CLK_DELAY) | 0x80000011); - cx_write(ALT_PIN_OUT_SEL, 0x10100045); - } - - switch (dev->bridge) { - case CX23885_BRIDGE_885: - case CX23885_BRIDGE_887: - /* enable irqs */ - dprintk(1, "%s() enabling TS int's and DMA\n", __func__); - cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); - cx_set(port->reg_dma_ctl, port->dma_ctl_val); - cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); - break; - default: - BUG(); - } - - cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - cx23885_av_clk(dev, 1); - - if (debug > 4) - cx23885_tsport_reg_dump(port); - - return 0; -} - -static int cx23885_stop_dma(struct cx23885_tsport *port) -{ - struct cx23885_dev *dev = port->dev; - u32 reg; - - dprintk(1, "%s()\n", __func__); - - /* Stop interrupts and DMA */ - cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { - - reg = cx_read(PAD_CTRL); - - /* Set TS1_OE */ - reg = reg | 0x1; - - /* clear TS1_SOP_OE and TS1_OE_HI */ - reg = reg & ~0xa; - cx_write(PAD_CTRL, reg); - cx_write(port->reg_src_sel, 0); - cx_write(port->reg_gen_ctrl, 8); - - } - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - cx23885_av_clk(dev, 0); - - return 0; -} - -int cx23885_restart_queue(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_buffer *buf; - - dprintk(5, "%s()\n", __func__); - if (list_empty(&q->active)) { - struct cx23885_buffer *prev; - prev = NULL; - - dprintk(5, "%s() queue is empty\n", __func__); - - for (;;) { - if (list_empty(&q->queued)) - return 0; - buf = list_entry(q->queued.next, struct cx23885_buffer, - vb.queue); - if (NULL == prev) { - list_del(&buf->vb.queue); - list_add_tail(&buf->vb.queue, &q->active); - cx23885_start_dma(port, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(5, "[%p/%d] restart_queue - f/active\n", - buf, buf->vb.i); - - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_del(&buf->vb.queue); - list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - /* 64 bit bits 63-32 */ - prev->risc.jmp[2] = cpu_to_le32(0); - dprintk(5, "[%p/%d] restart_queue - m/active\n", - buf, buf->vb.i); - } else { - return 0; - } - prev = buf; - } - return 0; - } - - buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); - dprintk(2, "restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); - cx23885_start_dma(port, q, buf); - list_for_each_entry(buf, &q->active, vb.queue) - buf->count = q->count++; - mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); - return 0; -} - -/* ------------------------------------------------------------------ */ - -int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, - struct cx23885_buffer *buf, enum v4l2_field field) -{ - struct cx23885_dev *dev = port->dev; - int size = port->ts_packet_size * port->ts_packet_count; - int rc; - - dprintk(1, "%s: %p\n", __func__, buf); - if (0 != buf->vb.baddr && buf->vb.bsize < size) - return -EINVAL; - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - buf->vb.width = port->ts_packet_size; - buf->vb.height = port->ts_packet_count; - buf->vb.size = size; - buf->vb.field = field /*V4L2_FIELD_TOP*/; - - rc = videobuf_iolock(q, &buf->vb, NULL); - if (0 != rc) - goto fail; - cx23885_risc_databuffer(dev->pci, &buf->risc, - videobuf_to_dma(&buf->vb)->sglist, - buf->vb.width, buf->vb.height); - } - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - - fail: - cx23885_free_buffer(q, buf); - return rc; -} - -void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) -{ - struct cx23885_buffer *prev; - struct cx23885_dev *dev = port->dev; - struct cx23885_dmaqueue *cx88q = &port->mpegq; - - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); - buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ - - if (list_empty(&cx88q->active)) { - dprintk(1, "queue is empty - first active\n"); - list_add_tail(&buf->vb.queue, &cx88q->active); - cx23885_start_dma(port, cx88q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = cx88q->count++; - mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); - dprintk(1, "[%p/%d] %s - first active\n", - buf, buf->vb.i, __func__); - } else { - dprintk(1, "queue is not empty - append to active\n"); - prev = list_entry(cx88q->active.prev, struct cx23885_buffer, - vb.queue); - list_add_tail(&buf->vb.queue, &cx88q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = cx88q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ - dprintk(1, "[%p/%d] %s - append to active\n", - buf, buf->vb.i, __func__); - } -} - -/* ----------------------------------------------------------- */ - -static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, - int restart) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_dmaqueue *q = &port->mpegq; - struct cx23885_buffer *buf; - unsigned long flags; - - spin_lock_irqsave(&port->slock, flags); - while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx23885_buffer, - vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - dprintk(1, "[%p/%d] %s - dma=0x%08lx\n", - buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); - } - if (restart) { - dprintk(1, "restarting queue\n"); - cx23885_restart_queue(port, q); - } - spin_unlock_irqrestore(&port->slock, flags); -} - -void cx23885_cancel_buffers(struct cx23885_tsport *port) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_dmaqueue *q = &port->mpegq; - - dprintk(1, "%s()\n", __func__); - del_timer_sync(&q->timeout); - cx23885_stop_dma(port); - do_cancel_buffers(port, "cancel", 0); -} - -static void cx23885_timeout(unsigned long data) -{ - struct cx23885_tsport *port = (struct cx23885_tsport *)data; - struct cx23885_dev *dev = port->dev; - - dprintk(1, "%s()\n", __func__); - - if (debug > 5) - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); - - cx23885_stop_dma(port); - do_cancel_buffers(port, "timeout", 1); -} - -int cx23885_irq_417(struct cx23885_dev *dev, u32 status) -{ - /* FIXME: port1 assumption here. */ - struct cx23885_tsport *port = &dev->ts1; - int count = 0; - int handled = 0; - - if (status == 0) - return handled; - - count = cx_read(port->reg_gpcnt); - dprintk(7, "status: 0x%08x mask: 0x%08x count: 0x%x\n", - status, cx_read(port->reg_ts_int_msk), count); - - if ((status & VID_B_MSK_BAD_PKT) || - (status & VID_B_MSK_OPC_ERR) || - (status & VID_B_MSK_VBI_OPC_ERR) || - (status & VID_B_MSK_SYNC) || - (status & VID_B_MSK_VBI_SYNC) || - (status & VID_B_MSK_OF) || - (status & VID_B_MSK_VBI_OF)) { - printk(KERN_ERR "%s: V4L mpeg risc op code error, status " - "= 0x%x\n", dev->name, status); - if (status & VID_B_MSK_BAD_PKT) - dprintk(1, " VID_B_MSK_BAD_PKT\n"); - if (status & VID_B_MSK_OPC_ERR) - dprintk(1, " VID_B_MSK_OPC_ERR\n"); - if (status & VID_B_MSK_VBI_OPC_ERR) - dprintk(1, " VID_B_MSK_VBI_OPC_ERR\n"); - if (status & VID_B_MSK_SYNC) - dprintk(1, " VID_B_MSK_SYNC\n"); - if (status & VID_B_MSK_VBI_SYNC) - dprintk(1, " VID_B_MSK_VBI_SYNC\n"); - if (status & VID_B_MSK_OF) - dprintk(1, " VID_B_MSK_OF\n"); - if (status & VID_B_MSK_VBI_OF) - dprintk(1, " VID_B_MSK_VBI_OF\n"); - - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); - cx23885_417_check_encoder(dev); - } else if (status & VID_B_MSK_RISCI1) { - dprintk(7, " VID_B_MSK_RISCI1\n"); - spin_lock(&port->slock); - cx23885_wakeup(port, &port->mpegq, count); - spin_unlock(&port->slock); - } else if (status & VID_B_MSK_RISCI2) { - dprintk(7, " VID_B_MSK_RISCI2\n"); - spin_lock(&port->slock); - cx23885_restart_queue(port, &port->mpegq); - spin_unlock(&port->slock); - } - if (status) { - cx_write(port->reg_ts_int_stat, status); - handled = 1; - } - - return handled; -} - -static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) -{ - struct cx23885_dev *dev = port->dev; - int handled = 0; - u32 count; - - if ((status & VID_BC_MSK_OPC_ERR) || - (status & VID_BC_MSK_BAD_PKT) || - (status & VID_BC_MSK_SYNC) || - (status & VID_BC_MSK_OF)) { - - if (status & VID_BC_MSK_OPC_ERR) - dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", - VID_BC_MSK_OPC_ERR); - - if (status & VID_BC_MSK_BAD_PKT) - dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", - VID_BC_MSK_BAD_PKT); - - if (status & VID_BC_MSK_SYNC) - dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", - VID_BC_MSK_SYNC); - - if (status & VID_BC_MSK_OF) - dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", - VID_BC_MSK_OF); - - printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); - - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); - - } else if (status & VID_BC_MSK_RISCI1) { - - dprintk(7, " (RISCI1 0x%08x)\n", VID_BC_MSK_RISCI1); - - spin_lock(&port->slock); - count = cx_read(port->reg_gpcnt); - cx23885_wakeup(port, &port->mpegq, count); - spin_unlock(&port->slock); - - } else if (status & VID_BC_MSK_RISCI2) { - - dprintk(7, " (RISCI2 0x%08x)\n", VID_BC_MSK_RISCI2); - - spin_lock(&port->slock); - cx23885_restart_queue(port, &port->mpegq); - spin_unlock(&port->slock); - - } - if (status) { - cx_write(port->reg_ts_int_stat, status); - handled = 1; - } - - return handled; -} - -static irqreturn_t cx23885_irq(int irq, void *dev_id) -{ - struct cx23885_dev *dev = dev_id; - struct cx23885_tsport *ts1 = &dev->ts1; - struct cx23885_tsport *ts2 = &dev->ts2; - u32 pci_status, pci_mask; - u32 vida_status, vida_mask; - u32 ts1_status, ts1_mask; - u32 ts2_status, ts2_mask; - int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0; - - pci_status = cx_read(PCI_INT_STAT); - pci_mask = cx_read(PCI_INT_MSK); - vida_status = cx_read(VID_A_INT_STAT); - vida_mask = cx_read(VID_A_INT_MSK); - ts1_status = cx_read(VID_B_INT_STAT); - ts1_mask = cx_read(VID_B_INT_MSK); - ts2_status = cx_read(VID_C_INT_STAT); - ts2_mask = cx_read(VID_C_INT_MSK); - - if ((pci_status == 0) && (ts2_status == 0) && (ts1_status == 0)) - goto out; - - vida_count = cx_read(VID_A_GPCNT); - ts1_count = cx_read(ts1->reg_gpcnt); - ts2_count = cx_read(ts2->reg_gpcnt); - dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n", - pci_status, pci_mask); - dprintk(7, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n", - vida_status, vida_mask, vida_count); - dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n", - ts1_status, ts1_mask, ts1_count); - dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", - ts2_status, ts2_mask, ts2_count); - - if ((pci_status & PCI_MSK_RISC_RD) || - (pci_status & PCI_MSK_RISC_WR) || - (pci_status & PCI_MSK_AL_RD) || - (pci_status & PCI_MSK_AL_WR) || - (pci_status & PCI_MSK_APB_DMA) || - (pci_status & PCI_MSK_VID_C) || - (pci_status & PCI_MSK_VID_B) || - (pci_status & PCI_MSK_VID_A) || - (pci_status & PCI_MSK_AUD_INT) || - (pci_status & PCI_MSK_AUD_EXT)) { - - if (pci_status & PCI_MSK_RISC_RD) - dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", - PCI_MSK_RISC_RD); - - if (pci_status & PCI_MSK_RISC_WR) - dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", - PCI_MSK_RISC_WR); - - if (pci_status & PCI_MSK_AL_RD) - dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", - PCI_MSK_AL_RD); - - if (pci_status & PCI_MSK_AL_WR) - dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", - PCI_MSK_AL_WR); - - if (pci_status & PCI_MSK_APB_DMA) - dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", - PCI_MSK_APB_DMA); - - if (pci_status & PCI_MSK_VID_C) - dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", - PCI_MSK_VID_C); - - if (pci_status & PCI_MSK_VID_B) - dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", - PCI_MSK_VID_B); - - if (pci_status & PCI_MSK_VID_A) - dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", - PCI_MSK_VID_A); - - if (pci_status & PCI_MSK_AUD_INT) - dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", - PCI_MSK_AUD_INT); - - if (pci_status & PCI_MSK_AUD_EXT) - dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", - PCI_MSK_AUD_EXT); - - } - - if (ts1_status) { - if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) - handled += cx23885_irq_ts(ts1, ts1_status); - else - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - handled += cx23885_irq_417(dev, ts1_status); - } - - if (ts2_status) { - if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) - handled += cx23885_irq_ts(ts2, ts2_status); - else - if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) - handled += cx23885_irq_417(dev, ts2_status); - } - - if (vida_status) - handled += cx23885_video_irq(dev, vida_status); - - if (handled) - cx_write(PCI_INT_STAT, pci_status); -out: - return IRQ_RETVAL(handled); -} - -static int __devinit cx23885_initdev(struct pci_dev *pci_dev, - const struct pci_device_id *pci_id) -{ - struct cx23885_dev *dev; - int err; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (NULL == dev) - return -ENOMEM; - - /* pci init */ - dev->pci = pci_dev; - if (pci_enable_device(pci_dev)) { - err = -EIO; - goto fail_free; - } - - if (cx23885_dev_setup(dev) < 0) { - err = -EINVAL; - goto fail_free; - } - - /* print pci info */ - pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); - pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", dev->name, - pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat, - (unsigned long long)pci_resource_start(pci_dev, 0)); - - pci_set_master(pci_dev); - if (!pci_dma_supported(pci_dev, 0xffffffff)) { - printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); - err = -EIO; - goto fail_irq; - } - - err = request_irq(pci_dev->irq, cx23885_irq, - IRQF_SHARED | IRQF_DISABLED, dev->name, dev); - if (err < 0) { - printk(KERN_ERR "%s: can't get IRQ %d\n", - dev->name, pci_dev->irq); - goto fail_irq; - } - - pci_set_drvdata(pci_dev, dev); - return 0; - -fail_irq: - cx23885_dev_unregister(dev); -fail_free: - kfree(dev); - return err; -} - -static void __devexit cx23885_finidev(struct pci_dev *pci_dev) -{ - struct cx23885_dev *dev = pci_get_drvdata(pci_dev); - - cx23885_shutdown(dev); - - pci_disable_device(pci_dev); - - /* unregister stuff */ - free_irq(pci_dev->irq, dev); - pci_set_drvdata(pci_dev, NULL); - - mutex_lock(&devlist); - list_del(&dev->devlist); - mutex_unlock(&devlist); - - cx23885_dev_unregister(dev); - kfree(dev); -} - -static struct pci_device_id cx23885_pci_tbl[] = { - { - /* CX23885 */ - .vendor = 0x14f1, - .device = 0x8852, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { - /* CX23887 Rev 2 */ - .vendor = 0x14f1, - .device = 0x8880, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { - /* --- end of list --- */ - } -}; -MODULE_DEVICE_TABLE(pci, cx23885_pci_tbl); - -static struct pci_driver cx23885_pci_driver = { - .name = "cx23885", - .id_table = cx23885_pci_tbl, - .probe = cx23885_initdev, - .remove = __devexit_p(cx23885_finidev), - /* TODO */ - .suspend = NULL, - .resume = NULL, -}; - -static int cx23885_init(void) -{ - printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n", - (CX23885_VERSION_CODE >> 16) & 0xff, - (CX23885_VERSION_CODE >> 8) & 0xff, - CX23885_VERSION_CODE & 0xff); -#ifdef SNAPSHOT - printk(KERN_INFO "cx23885: snapshot date %04d-%02d-%02d\n", - SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); -#endif - return pci_register_driver(&cx23885_pci_driver); -} - -static void cx23885_fini(void) -{ - pci_unregister_driver(&cx23885_pci_driver); -} - -module_init(cx23885_init); -module_exit(cx23885_fini); - -/* ----------------------------------------------------------- */ diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c deleted file mode 100644 index 1c454128a9d..00000000000 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 Steven Toth <stoth@linuxtv.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/device.h> -#include <linux/fs.h> -#include <linux/kthread.h> -#include <linux/file.h> -#include <linux/suspend.h> - -#include "cx23885.h" -#include <media/v4l2-common.h> - -#include "s5h1409.h" -#include "s5h1411.h" -#include "mt2131.h" -#include "tda8290.h" -#include "tda18271.h" -#include "lgdt330x.h" -#include "xc5000.h" -#include "tda10048.h" -#include "tuner-xc2028.h" -#include "tuner-simple.h" -#include "dib7000p.h" -#include "dibx000_common.h" -#include "zl10353.h" - -static unsigned int debug; - -#define dprintk(level, fmt, arg...)\ - do { if (debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ - } while (0) - -/* ------------------------------------------------------------------ */ - -static unsigned int alt_tuner; -module_param(alt_tuner, int, 0644); -MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -/* ------------------------------------------------------------------ */ - -static int dvb_buf_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) -{ - struct cx23885_tsport *port = q->priv_data; - - port->ts_packet_size = 188 * 4; - port->ts_packet_count = 32; - - *size = port->ts_packet_size * port->ts_packet_count; - *count = 32; - return 0; -} - -static int dvb_buf_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, enum v4l2_field field) -{ - struct cx23885_tsport *port = q->priv_data; - return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field); -} - -static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct cx23885_tsport *port = q->priv_data; - cx23885_buf_queue(port, (struct cx23885_buffer *)vb); -} - -static void dvb_buf_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - cx23885_free_buffer(q, (struct cx23885_buffer *)vb); -} - -static struct videobuf_queue_ops dvb_qops = { - .buf_setup = dvb_buf_setup, - .buf_prepare = dvb_buf_prepare, - .buf_queue = dvb_buf_queue, - .buf_release = dvb_buf_release, -}; - -static struct s5h1409_config hauppauge_generic_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_ON, - .qam_if = 44000, - .inversion = S5H1409_INVERSION_OFF, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct tda10048_config hauppauge_hvr1200_config = { - .demod_address = 0x10 >> 1, - .output_mode = TDA10048_SERIAL_OUTPUT, - .fwbulkwritelen = TDA10048_BULKWRITE_200, - .inversion = TDA10048_INVERSION_ON -}; - -static struct s5h1409_config hauppauge_ezqam_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_OFF, - .qam_if = 4000, - .inversion = S5H1409_INVERSION_ON, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct s5h1409_config hauppauge_hvr1800lp_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_OFF, - .qam_if = 44000, - .inversion = S5H1409_INVERSION_OFF, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct s5h1409_config hauppauge_hvr1500_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_OFF, - .inversion = S5H1409_INVERSION_OFF, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct mt2131_config hauppauge_generic_tunerconfig = { - 0x61 -}; - -static struct lgdt330x_config fusionhdtv_5_express = { - .demod_address = 0x0e, - .demod_chip = LGDT3303, - .serial_mpeg = 0x40, -}; - -static struct s5h1409_config hauppauge_hvr1500q_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_ON, - .qam_if = 44000, - .inversion = S5H1409_INVERSION_OFF, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct s5h1409_config dvico_s5h1409_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_ON, - .qam_if = 44000, - .inversion = S5H1409_INVERSION_OFF, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct s5h1411_config dvico_s5h1411_config = { - .output_mode = S5H1411_SERIAL_OUTPUT, - .gpio = S5H1411_GPIO_ON, - .qam_if = S5H1411_IF_44000, - .vsb_if = S5H1411_IF_44000, - .inversion = S5H1411_INVERSION_OFF, - .status_mode = S5H1411_DEMODLOCKING, - .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { - .i2c_address = 0x61, - .if_khz = 5380, -}; - -static struct xc5000_config dvico_xc5000_tunerconfig = { - .i2c_address = 0x64, - .if_khz = 5380, -}; - -static struct tda829x_config tda829x_no_probe = { - .probe_tuner = TDA829X_DONT_PROBE, -}; - -static struct tda18271_std_map hauppauge_tda18271_std_map = { - .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, - .if_lvl = 6, .rfagc_top = 0x37 }, - .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, - .if_lvl = 6, .rfagc_top = 0x37 }, -}; - -static struct tda18271_config hauppauge_tda18271_config = { - .std_map = &hauppauge_tda18271_std_map, - .gate = TDA18271_GATE_ANALOG, -}; - -static struct tda18271_config hauppauge_hvr1200_tuner_config = { - .gate = TDA18271_GATE_ANALOG, -}; - -static struct dibx000_agc_config xc3028_agc_config = { - BAND_VHF | BAND_UHF, /* band_caps */ - - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0, - * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, - * P_agc_nb_est=2, P_agc_write=0 - */ - (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | - (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */ - - 712, /* inv_gain */ - 21, /* time_stabiliz */ - - 0, /* alpha_level */ - 118, /* thlock */ - - 0, /* wbd_inv */ - 2867, /* wbd_ref */ - 0, /* wbd_sel */ - 2, /* wbd_alpha */ - - 0, /* agc1_max */ - 0, /* agc1_min */ - 39718, /* agc2_max */ - 9930, /* agc2_min */ - 0, /* agc1_pt1 */ - 0, /* agc1_pt2 */ - 0, /* agc1_pt3 */ - 0, /* agc1_slope1 */ - 0, /* agc1_slope2 */ - 0, /* agc2_pt1 */ - 128, /* agc2_pt2 */ - 29, /* agc2_slope1 */ - 29, /* agc2_slope2 */ - - 17, /* alpha_mant */ - 27, /* alpha_exp */ - 23, /* beta_mant */ - 51, /* beta_exp */ - - 1, /* perform_agc_softsplit */ -}; - -/* PLL Configuration for COFDM BW_MHz = 8.000000 - * With external clock = 30.000000 */ -static struct dibx000_bandwidth_config xc3028_bw_config = { - 60000, /* internal */ - 30000, /* sampling */ - 1, /* pll_cfg: prediv */ - 8, /* pll_cfg: ratio */ - 3, /* pll_cfg: range */ - 1, /* pll_cfg: reset */ - 0, /* pll_cfg: bypass */ - 0, /* misc: refdiv */ - 0, /* misc: bypclk_div */ - 1, /* misc: IO_CLK_en_core */ - 1, /* misc: ADClkSrc */ - 0, /* misc: modulo */ - (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */ - (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */ - 20452225, /* timf */ - 30000000 /* xtal_hz */ -}; - -static struct dib7000p_config hauppauge_hvr1400_dib7000_config = { - .output_mpeg2_in_188_bytes = 1, - .hostbus_diversity = 1, - .tuner_is_baseband = 0, - .update_lna = NULL, - - .agc_config_count = 1, - .agc = &xc3028_agc_config, - .bw = &xc3028_bw_config, - - .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - - .pwm_freq_div = 0, - .agc_control = NULL, - .spur_protect = 0, - - .output_mode = OUTMODE_MPEG2_SERIAL, -}; - -static struct zl10353_config dvico_fusionhdtv_xc3028 = { - .demod_address = 0x0f, - .if2 = 45600, - .no_tuner = 1, -}; - -static int dvb_register(struct cx23885_tsport *port) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_i2c *i2c_bus = NULL; - struct videobuf_dvb_frontend *fe0; - - /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); - if (!fe0) - return -EINVAL; - - /* init struct videobuf_dvb */ - fe0->dvb.name = dev->name; - - /* init frontend */ - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &hauppauge_generic_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800: - i2c_bus = &dev->i2c_bus[0]; - switch (alt_tuner) { - case 1: - fe0->dvb.frontend = - dvb_attach(s5h1409_attach, - &hauppauge_ezqam_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, - &dev->i2c_bus[1].i2c_adap, 0x42, - &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_tda18271_config); - } - break; - case 0: - default: - fe0->dvb.frontend = - dvb_attach(s5h1409_attach, - &hauppauge_generic_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - break; - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &hauppauge_hvr1800lp_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - } - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(lgdt330x_attach, - &fusionhdtv_5_express, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, 0x61, - TUNER_LG_TDVS_H06XF); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - i2c_bus = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &hauppauge_hvr1500q_config, - &dev->i2c_bus[0].i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(xc5000_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_hvr1500q_tunerconfig); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500: - i2c_bus = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &hauppauge_hvr1500_config, - &dev->i2c_bus[0].i2c_adap); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &i2c_bus->i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .scode_table = XC3028_FE_OREN538, - }; - - fe = dvb_attach(xc2028_attach, - fe0->dvb.frontend, &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1200: - case CX23885_BOARD_HAUPPAUGE_HVR1700: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(tda10048_attach, - &hauppauge_hvr1200_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, - &dev->i2c_bus[1].i2c_adap, 0x42, - &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_hvr1200_tuner_config); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1400: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(dib7000p_attach, - &i2c_bus->i2c_adap, - 0x12, &hauppauge_hvr1400_dib7000_config); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &dev->i2c_bus[1].i2c_adap, - .i2c_addr = 0x64, - }; - static struct xc2028_ctrl ctl = { - .fname = XC3028L_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = 5000, - /* This is true for all demods with - v36 firmware? */ - .type = XC2028_D2633, - }; - - fe = dvb_attach(xc2028_attach, - fe0->dvb.frontend, &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - i2c_bus = &dev->i2c_bus[port->nr - 1]; - - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &dvico_s5h1409_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend == NULL) - fe0->dvb.frontend = dvb_attach(s5h1411_attach, - &dvico_s5h1411_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(xc5000_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &dvico_xc5000_tunerconfig); - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { - i2c_bus = &dev->i2c_bus[port->nr - 1]; - - fe0->dvb.frontend = dvb_attach(zl10353_attach, - &dvico_fusionhdtv_xc3028, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &i2c_bus->i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_ZARLINK456, - }; - - fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, - &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - } - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - i2c_bus = &dev->i2c_bus[0]; - - fe0->dvb.frontend = dvb_attach(zl10353_attach, - &dvico_fusionhdtv_xc3028, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &dev->i2c_bus[1].i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_ZARLINK456, - }; - - fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, - &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - default: - printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " - " isn't supported yet\n", - dev->name); - break; - } - if (NULL == fe0->dvb.frontend) { - printk(KERN_ERR "%s: frontend initialization failed\n", - dev->name); - return -1; - } - /* define general-purpose callback pointer */ - fe0->dvb.frontend->callback = cx23885_tuner_callback; - - /* Put the analog decoder in standby to keep it quiet */ - cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); - - if (fe0->dvb.frontend->ops.analog_ops.standby) - fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); - - /* register everything */ - return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, - &dev->pci->dev, adapter_nr, 0); - -} - -int cx23885_dvb_register(struct cx23885_tsport *port) -{ - - struct videobuf_dvb_frontend *fe0; - struct cx23885_dev *dev = port->dev; - int err, i; - - /* Here we need to allocate the correct number of frontends, - * as reflected in the cards struct. The reality is that currrently - * no cx23885 boards support this - yet. But, if we don't modify this - * code then the second frontend would never be allocated (later) - * and fail with error before the attach in dvb_register(). - * Without these changes we risk an OOPS later. The changes here - * are for safety, and should provide a good foundation for the - * future addition of any multi-frontend cx23885 based boards. - */ - printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, - port->num_frontends); - - for (i = 1; i <= port->num_frontends; i++) { - if (videobuf_dvb_alloc_frontend( - &port->frontends, i) == NULL) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); - return -ENOMEM; - } - - fe0 = videobuf_dvb_get_frontend(&port->frontends, i); - if (!fe0) - err = -EINVAL; - - dprintk(1, "%s\n", __func__); - dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", - dev->board, - dev->name, - dev->pci_bus, - dev->pci_slot); - - err = -ENODEV; - - /* dvb stuff */ - /* We have to init the queue for each frontend on a port. */ - printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); - videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, - &dev->pci->dev, &port->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, - sizeof(struct cx23885_buffer), port); - } - err = dvb_register(port); - if (err != 0) - printk(KERN_ERR "%s() dvb_register failed err = %d\n", - __func__, err); - - return err; -} - -int cx23885_dvb_unregister(struct cx23885_tsport *port) -{ - struct videobuf_dvb_frontend *fe0; - - /* FIXME: in an error condition where the we have - * an expected number of frontends (attach problem) - * then this might not clean up correctly, if 1 - * is invalid. - * This comment only applies to future boards IF they - * implement MFE support. - */ - fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); - if (fe0->dvb.frontend) - videobuf_dvb_unregister_bus(&port->frontends); - - return 0; -} - diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c deleted file mode 100644 index bb7f71a1fcb..00000000000 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 Steven Toth <stoth@linuxtv.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/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <asm/io.h> - -#include "cx23885.h" - -#include <media/v4l2-common.h> - -static unsigned int i2c_debug; -module_param(i2c_debug, int, 0644); -MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); - -static unsigned int i2c_scan; -module_param(i2c_scan, int, 0444); -MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); - -#define dprintk(level, fmt, arg...)\ - do { if (i2c_debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ - } while (0) - -#define I2C_WAIT_DELAY 32 -#define I2C_WAIT_RETRY 64 - -#define I2C_EXTEND (1 << 3) -#define I2C_NOSTOP (1 << 4) - -static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - return cx_read(bus->reg_stat) & 0x01; -} - -static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - return cx_read(bus->reg_stat) & 0x02 ? 1 : 0; -} - -static int i2c_wait_done(struct i2c_adapter *i2c_adap) -{ - int count; - - for (count = 0; count < I2C_WAIT_RETRY; count++) { - if (!i2c_is_busy(i2c_adap)) - break; - udelay(I2C_WAIT_DELAY); - } - - if (I2C_WAIT_RETRY == count) - return 0; - - return 1; -} - -static int i2c_sendbytes(struct i2c_adapter *i2c_adap, - const struct i2c_msg *msg, int joined_rlen) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - u32 wdata, addr, ctrl; - int retval, cnt; - - if (joined_rlen) - dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, - msg->len, joined_rlen); - else - dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); - - /* Deal with i2c probe functions with zero payload */ - if (msg->len == 0) { - cx_write(bus->reg_addr, msg->addr << 25); - cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2)); - if (!i2c_wait_done(i2c_adap)) - return -EIO; - if (!i2c_slave_did_ack(i2c_adap)) - return -EIO; - - dprintk(1, "%s() returns 0\n", __func__); - return 0; - } - - - /* dev, reg + first byte */ - addr = (msg->addr << 25) | msg->buf[0]; - wdata = msg->buf[0]; - ctrl = bus->i2c_period | (1 << 12) | (1 << 2); - - if (msg->len > 1) - ctrl |= I2C_NOSTOP | I2C_EXTEND; - else if (joined_rlen) - ctrl |= I2C_NOSTOP; - - cx_write(bus->reg_addr, addr); - cx_write(bus->reg_wdata, wdata); - cx_write(bus->reg_ctrl, ctrl); - - retval = i2c_wait_done(i2c_adap); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - if (i2c_debug) { - printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]); - if (!(ctrl & I2C_NOSTOP)) - printk(" >\n"); - } - - for (cnt = 1; cnt < msg->len; cnt++) { - /* following bytes */ - wdata = msg->buf[cnt]; - ctrl = bus->i2c_period | (1 << 12) | (1 << 2); - - if (cnt < msg->len - 1) - ctrl |= I2C_NOSTOP | I2C_EXTEND; - else if (joined_rlen) - ctrl |= I2C_NOSTOP; - - cx_write(bus->reg_addr, addr); - cx_write(bus->reg_wdata, wdata); - cx_write(bus->reg_ctrl, ctrl); - - retval = i2c_wait_done(i2c_adap); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - if (i2c_debug) { - dprintk(1, " %02x", msg->buf[cnt]); - if (!(ctrl & I2C_NOSTOP)) - dprintk(1, " >\n"); - } - } - return msg->len; - - eio: - retval = -EIO; - err: - if (i2c_debug) - printk(KERN_ERR " ERR: %d\n", retval); - return retval; -} - -static int i2c_readbytes(struct i2c_adapter *i2c_adap, - const struct i2c_msg *msg, int joined) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - u32 ctrl, cnt; - int retval; - - - if (i2c_debug && !joined) - dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); - - /* Deal with i2c probe functions with zero payload */ - if (msg->len == 0) { - cx_write(bus->reg_addr, msg->addr << 25); - cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1); - if (!i2c_wait_done(i2c_adap)) - return -EIO; - if (!i2c_slave_did_ack(i2c_adap)) - return -EIO; - - - dprintk(1, "%s() returns 0\n", __func__); - return 0; - } - - if (i2c_debug) { - if (joined) - dprintk(1, " R"); - else - dprintk(1, " <R %02x", (msg->addr << 1) + 1); - } - - for (cnt = 0; cnt < msg->len; cnt++) { - - ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; - - if (cnt < msg->len - 1) - ctrl |= I2C_NOSTOP | I2C_EXTEND; - - cx_write(bus->reg_addr, msg->addr << 25); - cx_write(bus->reg_ctrl, ctrl); - - retval = i2c_wait_done(i2c_adap); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; - if (i2c_debug) { - dprintk(1, " %02x", msg->buf[cnt]); - if (!(ctrl & I2C_NOSTOP)) - dprintk(1, " >\n"); - } - } - return msg->len; - - eio: - retval = -EIO; - err: - if (i2c_debug) - printk(KERN_ERR " ERR: %d\n", retval); - return retval; -} - -static int i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - int i, retval = 0; - - dprintk(1, "%s(num = %d)\n", __func__, num); - - for (i = 0 ; i < num; i++) { - dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", - __func__, num, msgs[i].addr, msgs[i].len); - if (msgs[i].flags & I2C_M_RD) { - /* read */ - retval = i2c_readbytes(i2c_adap, &msgs[i], 0); - } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && - msgs[i].addr == msgs[i + 1].addr) { - /* write then read from same address */ - retval = i2c_sendbytes(i2c_adap, &msgs[i], - msgs[i + 1].len); - if (retval < 0) - goto err; - i++; - retval = i2c_readbytes(i2c_adap, &msgs[i], 1); - } else { - /* write */ - retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); - } - if (retval < 0) - goto err; - } - return num; - - err: - return retval; -} - -static int attach_inform(struct i2c_client *client) -{ - struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter); - struct cx23885_dev *dev = bus->dev; - struct tuner_setup tun_setup; - - dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", - client->driver->driver.name, client->addr, client->name); - - if (!client->driver->command) - return 0; - - if (dev->tuner_type != UNSET) { - - dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n", - client->driver->driver.name, client->addr, - client->name); - - if ((dev->tuner_addr == ADDR_UNSET) || - (dev->tuner_addr == client->addr)) { - - dprintk(1, "%s (tuner || addr UNSET)\n", - client->driver->driver.name); - - dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", - client->driver->driver.name, - client->addr, client->name); - - tun_setup.mode_mask = T_ANALOG_TV; - tun_setup.type = dev->tuner_type; - tun_setup.addr = dev->tuner_addr; - - client->driver->command(client, TUNER_SET_TYPE_ADDR, - &tun_setup); - } - } - - return 0; -} - -static int detach_inform(struct i2c_client *client) -{ - struct cx23885_dev *dev = i2c_get_adapdata(client->adapter); - - dprintk(1, "i2c detach [client=%s]\n", client->name); - - return 0; -} - -void cx23885_call_i2c_clients(struct cx23885_i2c *bus, - unsigned int cmd, void *arg) -{ - if (bus->i2c_rc != 0) - return; - - i2c_clients_command(&bus->i2c_adap, cmd, arg); -} - -static u32 cx23885_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; -} - -static struct i2c_algorithm cx23885_i2c_algo_template = { - .master_xfer = i2c_xfer, - .functionality = cx23885_functionality, -}; - -/* ----------------------------------------------------------------------- */ - -static struct i2c_adapter cx23885_i2c_adap_template = { - .name = "cx23885", - .owner = THIS_MODULE, - .id = I2C_HW_B_CX23885, - .algo = &cx23885_i2c_algo_template, - .class = I2C_CLASS_TV_ANALOG, - .client_register = attach_inform, - .client_unregister = detach_inform, -}; - -static struct i2c_client cx23885_i2c_client_template = { - .name = "cx23885 internal", -}; - -static char *i2c_devs[128] = { - [0x10 >> 1] = "tda10048", - [0x12 >> 1] = "dib7000pc", - [0x1c >> 1] = "lgdt3303", - [0x86 >> 1] = "tda9887", - [0x32 >> 1] = "cx24227", - [0x88 >> 1] = "cx25837", - [0x84 >> 1] = "tda8295", - [0xa0 >> 1] = "eeprom", - [0xc0 >> 1] = "tuner/mt2131/tda8275", - [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028", - [0xc8 >> 1] = "tuner/xc3028L", -}; - -static void do_i2c_scan(char *name, struct i2c_client *c) -{ - unsigned char buf; - int i, rc; - - for (i = 0; i < 128; i++) { - c->addr = i; - rc = i2c_master_recv(c, &buf, 0); - if (rc < 0) - continue; - printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n", - name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); - } -} - -/* init + register i2c algo-bit adapter */ -int cx23885_i2c_register(struct cx23885_i2c *bus) -{ - struct cx23885_dev *dev = bus->dev; - - dprintk(1, "%s(bus = %d)\n", __func__, bus->nr); - - memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template, - sizeof(bus->i2c_adap)); - memcpy(&bus->i2c_algo, &cx23885_i2c_algo_template, - sizeof(bus->i2c_algo)); - memcpy(&bus->i2c_client, &cx23885_i2c_client_template, - sizeof(bus->i2c_client)); - - bus->i2c_adap.dev.parent = &dev->pci->dev; - - strlcpy(bus->i2c_adap.name, bus->dev->name, - sizeof(bus->i2c_adap.name)); - - bus->i2c_algo.data = bus; - bus->i2c_adap.algo_data = bus; - i2c_set_adapdata(&bus->i2c_adap, bus); - i2c_add_adapter(&bus->i2c_adap); - - bus->i2c_client.adapter = &bus->i2c_adap; - - if (0 == bus->i2c_rc) { - dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr); - if (i2c_scan) - do_i2c_scan(dev->name, &bus->i2c_client); - } else - printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", - dev->name, bus->nr); - - return bus->i2c_rc; -} - -int cx23885_i2c_unregister(struct cx23885_i2c *bus) -{ - i2c_del_adapter(&bus->i2c_adap); - return 0; -} - -void cx23885_av_clk(struct cx23885_dev *dev, int enable) -{ - /* write 0 to bus 2 addr 0x144 via i2x_xfer() */ - char buffer[3]; - struct i2c_msg msg; - dprintk(1, "%s(enabled = %d)\n", __func__, enable); - - /* Register 0x144 */ - buffer[0] = 0x01; - buffer[1] = 0x44; - if (enable == 1) - buffer[2] = 0x05; - else - buffer[2] = 0x00; - - msg.addr = 0x44; - msg.flags = I2C_M_TEN; - msg.len = 3; - msg.buf = buffer; - - i2c_xfer(&dev->i2c_bus[2].i2c_adap, &msg, 1); -} - -/* ----------------------------------------------------------------------- */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h deleted file mode 100644 index 20b68a23626..00000000000 --- a/drivers/media/video/cx23885/cx23885-reg.h +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 Steven Toth <stoth@linuxtv.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 _CX23885_REG_H_ -#define _CX23885_REG_H_ - -/* -Address Map -0x00000000 -> 0x00009000 TX SRAM (Fifos) -0x00010000 -> 0x00013c00 RX SRAM CMDS + CDT - -EACH CMDS struct is 0x80 bytes long - -DMAx_PTR1 = 0x03040 address of first cluster -DMAx_PTR2 = 0x10600 address of the CDT -DMAx_CNT1 = cluster size in (bytes >> 4) -1 -DMAx_CNT2 = total cdt size for all entries >> 3 - -Cluster Descriptor entry = 4 DWORDS - DWORD 0 -> ptr to cluster - DWORD 1 Reserved - DWORD 2 Reserved - DWORD 3 Reserved - -Channel manager Data Structure entry = 20 DWORD - 0 IntialProgramCounterLow - 1 IntialProgramCounterHigh - 2 ClusterDescriptorTableBase - 3 ClusterDescriptorTableSize - 4 InstructionQueueBase - 5 InstructionQueueSize -... Reserved - 19 Reserved -*/ - -/* Risc Instructions */ -#define RISC_CNT_INC 0x00010000 -#define RISC_CNT_RESET 0x00030000 -#define RISC_IRQ1 0x01000000 -#define RISC_IRQ2 0x02000000 -#define RISC_EOL 0x04000000 -#define RISC_SOL 0x08000000 -#define RISC_WRITE 0x10000000 -#define RISC_SKIP 0x20000000 -#define RISC_JUMP 0x70000000 -#define RISC_SYNC 0x80000000 -#define RISC_RESYNC 0x80008000 -#define RISC_READ 0x90000000 -#define RISC_WRITERM 0xB0000000 -#define RISC_WRITECM 0xC0000000 -#define RISC_WRITECR 0xD0000000 -#define RISC_WRITEC 0x50000000 -#define RISC_READC 0xA0000000 - - -/* Audio and Video Core */ -#define HOST_REG1 0x00000000 -#define HOST_REG2 0x00000001 -#define HOST_REG3 0x00000002 - -/* Chip Configuration Registers */ -#define CHIP_CTRL 0x00000100 -#define AFE_CTRL 0x00000104 -#define VID_PLL_INT_POST 0x00000108 -#define VID_PLL_FRAC 0x0000010C -#define AUX_PLL_INT_POST 0x00000110 -#define AUX_PLL_FRAC 0x00000114 -#define SYS_PLL_INT_POST 0x00000118 -#define SYS_PLL_FRAC 0x0000011C -#define PIN_CTRL 0x00000120 -#define AUD_IO_CTRL 0x00000124 -#define AUD_LOCK1 0x00000128 -#define AUD_LOCK2 0x0000012C -#define POWER_CTRL 0x00000130 -#define AFE_DIAG_CTRL1 0x00000134 -#define AFE_DIAG_CTRL3 0x0000013C -#define PLL_DIAG_CTRL 0x00000140 -#define AFE_CLK_OUT_CTRL 0x00000144 -#define DLL1_DIAG_CTRL 0x0000015C - -/* GPIO[23:19] Output Enable */ -#define GPIO2_OUT_EN_REG 0x00000160 -/* GPIO[23:19] Data Registers */ -#define GPIO2 0x00000164 - -#define IFADC_CTRL 0x00000180 - -/* Infrared Remote Registers */ -#define IR_CNTRL_REG 0x00000200 -#define IR_TXCLK_REG 0x00000204 -#define IR_RXCLK_REG 0x00000208 -#define IR_CDUTY_REG 0x0000020C -#define IR_STAT_REG 0x00000210 -#define IR_IRQEN_REG 0x00000214 -#define IR_FILTR_REG 0x00000218 -#define IR_FIFO_REG 0x0000023C - -/* Video Decoder Registers */ -#define MODE_CTRL 0x00000400 -#define OUT_CTRL1 0x00000404 -#define OUT_CTRL2 0x00000408 -#define GEN_STAT 0x0000040C -#define INT_STAT_MASK 0x00000410 -#define LUMA_CTRL 0x00000414 -#define HSCALE_CTRL 0x00000418 -#define VSCALE_CTRL 0x0000041C -#define CHROMA_CTRL 0x00000420 -#define VBI_LINE_CTRL1 0x00000424 -#define VBI_LINE_CTRL2 0x00000428 -#define VBI_LINE_CTRL3 0x0000042C -#define VBI_LINE_CTRL4 0x00000430 -#define VBI_LINE_CTRL5 0x00000434 -#define VBI_FC_CFG 0x00000438 -#define VBI_MISC_CFG1 0x0000043C -#define VBI_MISC_CFG2 0x00000440 -#define VBI_PAY1 0x00000444 -#define VBI_PAY2 0x00000448 -#define VBI_CUST1_CFG1 0x0000044C -#define VBI_CUST1_CFG2 0x00000450 -#define VBI_CUST1_CFG3 0x00000454 -#define VBI_CUST2_CFG1 0x00000458 -#define VBI_CUST2_CFG2 0x0000045C -#define VBI_CUST2_CFG3 0x00000460 -#define VBI_CUST3_CFG1 0x00000464 -#define VBI_CUST3_CFG2 0x00000468 -#define VBI_CUST3_CFG3 0x0000046C -#define HORIZ_TIM_CTRL 0x00000470 -#define VERT_TIM_CTRL 0x00000474 -#define SRC_COMB_CFG 0x00000478 -#define CHROMA_VBIOFF_CFG 0x0000047C -#define FIELD_COUNT 0x00000480 -#define MISC_TIM_CTRL 0x00000484 -#define DFE_CTRL1 0x00000488 -#define DFE_CTRL2 0x0000048C -#define DFE_CTRL3 0x00000490 -#define PLL_CTRL 0x00000494 -#define HTL_CTRL 0x00000498 -#define COMB_CTRL 0x0000049C -#define CRUSH_CTRL 0x000004A0 -#define SOFT_RST_CTRL 0x000004A4 -#define CX885_VERSION 0x000004B4 -#define VBI_PASS_CTRL 0x000004BC - -/* Audio Decoder Registers */ -/* 8051 Configuration */ -#define DL_CTL 0x00000800 -#define STD_DET_STATUS 0x00000804 -#define STD_DET_CTL 0x00000808 -#define DW8051_INT 0x0000080C -#define GENERAL_CTL 0x00000810 -#define AAGC_CTL 0x00000814 -#define DEMATRIX_CTL 0x000008CC -#define PATH1_CTL1 0x000008D0 -#define PATH1_VOL_CTL 0x000008D4 -#define PATH1_EQ_CTL 0x000008D8 -#define PATH1_SC_CTL 0x000008DC -#define PATH2_CTL1 0x000008E0 -#define PATH2_VOL_CTL 0x000008E4 -#define PATH2_EQ_CTL 0x000008E8 -#define PATH2_SC_CTL 0x000008EC - -/* Sample Rate Converter */ -#define SRC_CTL 0x000008F0 -#define SRC_LF_COEF 0x000008F4 -#define SRC1_CTL 0x000008F8 -#define SRC2_CTL 0x000008FC -#define SRC3_CTL 0x00000900 -#define SRC4_CTL 0x00000904 -#define SRC5_CTL 0x00000908 -#define SRC6_CTL 0x0000090C -#define BAND_OUT_SEL 0x00000910 -#define I2S_N_CTL 0x00000914 -#define I2S_OUT_CTL 0x00000918 -#define AUTOCONFIG_REG 0x000009C4 - -/* Audio ADC Registers */ -#define DSM_CTRL1 0x00000000 -#define DSM_CTRL2 0x00000001 -#define CHP_EN_CTRL 0x00000002 -#define CHP_CLK_CTRL1 0x00000004 -#define CHP_CLK_CTRL2 0x00000005 -#define BG_REF_CTRL 0x00000006 -#define SD2_SW_CTRL1 0x00000008 -#define SD2_SW_CTRL2 0x00000009 -#define SD2_BIAS_CTRL 0x0000000A -#define AMP_BIAS_CTRL 0x0000000C -#define CH_PWR_CTRL1 0x0000000E -#define CH_PWR_CTRL2 0x0000000F -#define DSM_STATUS1 0x00000010 -#define DSM_STATUS2 0x00000011 -#define DIG_CTL1 0x00000012 -#define DIG_CTL2 0x00000013 -#define I2S_TX_CFG 0x0000001A - -#define DEV_CNTRL2 0x00040000 - -#define PCI_MSK_APB_DMA (1 << 12) -#define PCI_MSK_AL_WR (1 << 11) -#define PCI_MSK_AL_RD (1 << 10) -#define PCI_MSK_RISC_WR (1 << 9) -#define PCI_MSK_RISC_RD (1 << 8) -#define PCI_MSK_AUD_EXT (1 << 4) -#define PCI_MSK_AUD_INT (1 << 3) -#define PCI_MSK_VID_C (1 << 2) -#define PCI_MSK_VID_B (1 << 1) -#define PCI_MSK_VID_A 1 -#define PCI_INT_MSK 0x00040010 - -#define PCI_INT_STAT 0x00040014 -#define PCI_INT_MSTAT 0x00040018 - -#define VID_A_INT_MSK 0x00040020 -#define VID_A_INT_STAT 0x00040024 -#define VID_A_INT_MSTAT 0x00040028 -#define VID_A_INT_SSTAT 0x0004002C - -#define VID_B_INT_MSK 0x00040030 -#define VID_B_MSK_BAD_PKT (1 << 20) -#define VID_B_MSK_VBI_OPC_ERR (1 << 17) -#define VID_B_MSK_OPC_ERR (1 << 16) -#define VID_B_MSK_VBI_SYNC (1 << 13) -#define VID_B_MSK_SYNC (1 << 12) -#define VID_B_MSK_VBI_OF (1 << 9) -#define VID_B_MSK_OF (1 << 8) -#define VID_B_MSK_VBI_RISCI2 (1 << 5) -#define VID_B_MSK_RISCI2 (1 << 4) -#define VID_B_MSK_VBI_RISCI1 (1 << 1) -#define VID_B_MSK_RISCI1 1 -#define VID_B_INT_STAT 0x00040034 -#define VID_B_INT_MSTAT 0x00040038 -#define VID_B_INT_SSTAT 0x0004003C - -#define VID_B_MSK_BAD_PKT (1 << 20) -#define VID_B_MSK_OPC_ERR (1 << 16) -#define VID_B_MSK_SYNC (1 << 12) -#define VID_B_MSK_OF (1 << 8) -#define VID_B_MSK_RISCI2 (1 << 4) -#define VID_B_MSK_RISCI1 1 - -#define VID_C_MSK_BAD_PKT (1 << 20) -#define VID_C_MSK_OPC_ERR (1 << 16) -#define VID_C_MSK_SYNC (1 << 12) -#define VID_C_MSK_OF (1 << 8) -#define VID_C_MSK_RISCI2 (1 << 4) -#define VID_C_MSK_RISCI1 1 - -/* A superset for testing purposes */ -#define VID_BC_MSK_BAD_PKT (1 << 20) -#define VID_BC_MSK_OPC_ERR (1 << 16) -#define VID_BC_MSK_SYNC (1 << 12) -#define VID_BC_MSK_OF (1 << 8) -#define VID_BC_MSK_RISCI2 (1 << 4) -#define VID_BC_MSK_RISCI1 1 - -#define VID_C_INT_MSK 0x00040040 -#define VID_C_INT_STAT 0x00040044 -#define VID_C_INT_MSTAT 0x00040048 -#define VID_C_INT_SSTAT 0x0004004C - -#define AUDIO_INT_INT_MSK 0x00040050 -#define AUDIO_INT_INT_STAT 0x00040054 -#define AUDIO_INT_INT_MSTAT 0x00040058 -#define AUDIO_INT_INT_SSTAT 0x0004005C - -#define AUDIO_EXT_INT_MSK 0x00040060 -#define AUDIO_EXT_INT_STAT 0x00040064 -#define AUDIO_EXT_INT_MSTAT 0x00040068 -#define AUDIO_EXT_INT_SSTAT 0x0004006C - -#define RDR_CFG0 0x00050000 -#define RDR_CFG1 0x00050004 -#define RDR_CFG2 0x00050008 -#define RDR_TLCTL0 0x00050318 - -/* APB DMAC Current Buffer Pointer */ -#define DMA1_PTR1 0x00100000 -#define DMA2_PTR1 0x00100004 -#define DMA3_PTR1 0x00100008 -#define DMA4_PTR1 0x0010000C -#define DMA5_PTR1 0x00100010 -#define DMA6_PTR1 0x00100014 -#define DMA7_PTR1 0x00100018 -#define DMA8_PTR1 0x0010001C - -/* APB DMAC Current Table Pointer */ -#define DMA1_PTR2 0x00100040 -#define DMA2_PTR2 0x00100044 -#define DMA3_PTR2 0x00100048 -#define DMA4_PTR2 0x0010004C -#define DMA5_PTR2 0x00100050 -#define DMA6_PTR2 0x00100054 -#define DMA7_PTR2 0x00100058 -#define DMA8_PTR2 0x0010005C - -/* APB DMAC Buffer Limit */ -#define DMA1_CNT1 0x00100080 -#define DMA2_CNT1 0x00100084 -#define DMA3_CNT1 0x00100088 -#define DMA4_CNT1 0x0010008C -#define DMA5_CNT1 0x00100090 -#define DMA6_CNT1 0x00100094 -#define DMA7_CNT1 0x00100098 -#define DMA8_CNT1 0x0010009C - -/* APB DMAC Table Size */ -#define DMA1_CNT2 0x001000C0 -#define DMA2_CNT2 0x001000C4 -#define DMA3_CNT2 0x001000C8 -#define DMA4_CNT2 0x001000CC -#define DMA5_CNT2 0x001000D0 -#define DMA6_CNT2 0x001000D4 -#define DMA7_CNT2 0x001000D8 -#define DMA8_CNT2 0x001000DC - -/* Timer Counters */ -#define TM_CNT_LDW 0x00110000 -#define TM_CNT_UW 0x00110004 -#define TM_LMT_LDW 0x00110008 -#define TM_LMT_UW 0x0011000C - -/* GPIO */ -#define GP0_IO 0x00110010 -#define GPIO_ISM 0x00110014 -#define SOFT_RESET 0x0011001C - -/* GPIO (417 Microsoftcontroller) RW Data */ -#define MC417_RWD 0x00110020 - -/* GPIO (417 Microsoftcontroller) Output Enable, Low Active */ -#define MC417_OEN 0x00110024 -#define MC417_CTL 0x00110028 -#define ALT_PIN_OUT_SEL 0x0011002C -#define CLK_DELAY 0x00110048 -#define PAD_CTRL 0x0011004C - -/* Video A Interface */ -#define VID_A_GPCNT 0x00130020 -#define VBI_A_GPCNT 0x00130024 -#define VID_A_GPCNT_CTL 0x00130030 -#define VBI_A_GPCNT_CTL 0x00130034 -#define VID_A_DMA_CTL 0x00130040 -#define VID_A_VIP_CTRL 0x00130080 -#define VID_A_PIXEL_FRMT 0x00130084 -#define VID_A_VBI_CTRL 0x00130088 - -/* Video B Interface */ -#define VID_B_DMA 0x00130100 -#define VBI_B_DMA 0x00130108 -#define VID_B_GPCNT 0x00130120 -#define VBI_B_GPCNT 0x00130124 -#define VID_B_GPCNT_CTL 0x00130134 -#define VBI_B_GPCNT_CTL 0x00130138 -#define VID_B_DMA_CTL 0x00130140 -#define VID_B_SRC_SEL 0x00130144 -#define VID_B_LNGTH 0x00130150 -#define VID_B_HW_SOP_CTL 0x00130154 -#define VID_B_GEN_CTL 0x00130158 -#define VID_B_BD_PKT_STATUS 0x0013015C -#define VID_B_SOP_STATUS 0x00130160 -#define VID_B_FIFO_OVFL_STAT 0x00130164 -#define VID_B_VLD_MISC 0x00130168 -#define VID_B_TS_CLK_EN 0x0013016C -#define VID_B_VIP_CTRL 0x00130180 -#define VID_B_PIXEL_FRMT 0x00130184 - -/* Video C Interface */ -#define VID_C_GPCNT 0x00130220 -#define VID_C_GPCNT_CTL 0x00130230 -#define VBI_C_GPCNT_CTL 0x00130234 -#define VID_C_DMA_CTL 0x00130240 -#define VID_C_LNGTH 0x00130250 -#define VID_C_HW_SOP_CTL 0x00130254 -#define VID_C_GEN_CTL 0x00130258 -#define VID_C_BD_PKT_STATUS 0x0013025C -#define VID_C_SOP_STATUS 0x00130260 -#define VID_C_FIFO_OVFL_STAT 0x00130264 -#define VID_C_VLD_MISC 0x00130268 -#define VID_C_TS_CLK_EN 0x0013026C - -/* Internal Audio Interface */ -#define AUD_INT_A_GPCNT 0x00140020 -#define AUD_INT_B_GPCNT 0x00140024 -#define AUD_INT_A_GPCNT_CTL 0x00140030 -#define AUD_INT_B_GPCNT_CTL 0x00140034 -#define AUD_INT_DMA_CTL 0x00140040 -#define AUD_INT_A_LNGTH 0x00140050 -#define AUD_INT_B_LNGTH 0x00140054 -#define AUD_INT_A_MODE 0x00140058 -#define AUD_INT_B_MODE 0x0014005C - -/* External Audio Interface */ -#define AUD_EXT_DMA 0x00140100 -#define AUD_EXT_GPCNT 0x00140120 -#define AUD_EXT_GPCNT_CTL 0x00140130 -#define AUD_EXT_DMA_CTL 0x00140140 -#define AUD_EXT_LNGTH 0x00140150 -#define AUD_EXT_A_MODE 0x00140158 - -/* I2C Bus 1 */ -#define I2C1_ADDR 0x00180000 -#define I2C1_WDATA 0x00180004 -#define I2C1_CTRL 0x00180008 -#define I2C1_RDATA 0x0018000C -#define I2C1_STAT 0x00180010 - -/* I2C Bus 2 */ -#define I2C2_ADDR 0x00190000 -#define I2C2_WDATA 0x00190004 -#define I2C2_CTRL 0x00190008 -#define I2C2_RDATA 0x0019000C -#define I2C2_STAT 0x00190010 - -/* I2C Bus 3 */ -#define I2C3_ADDR 0x001A0000 -#define I2C3_WDATA 0x001A0004 -#define I2C3_CTRL 0x001A0008 -#define I2C3_RDATA 0x001A000C -#define I2C3_STAT 0x001A0010 - -/* UART */ -#define UART_CTL 0x001B0000 -#define UART_BRD 0x001B0004 -#define UART_ISR 0x001B000C -#define UART_CNT 0x001B0010 - -#endif /* _CX23885_REG_H_ */ diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c deleted file mode 100644 index 5b297f0323b..00000000000 --- a/drivers/media/video/cx23885/cx23885-vbi.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2007 Steven Toth <stoth@linuxtv.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/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/slab.h> - -#include "cx23885.h" - -static unsigned int vbibufs = 4; -module_param(vbibufs, int, 0644); -MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32"); - -static unsigned int vbi_debug; -module_param(vbi_debug, int, 0644); -MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); - -#define dprintk(level, fmt, arg...)\ - do { if (vbi_debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ - } while (0) - -/* ------------------------------------------------------------------ */ - -int cx23885_vbi_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - if (dev->tvnorm & V4L2_STD_525_60) { - /* ntsc */ - f->fmt.vbi.sampling_rate = 28636363; - f->fmt.vbi.start[0] = 10; - f->fmt.vbi.start[1] = 273; - - } else if (dev->tvnorm & V4L2_STD_625_50) { - /* pal */ - f->fmt.vbi.sampling_rate = 35468950; - f->fmt.vbi.start[0] = 7 - 1; - f->fmt.vbi.start[1] = 319 - 1; - } - return 0; -} - -static int cx23885_start_vbi_dma(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q, - struct cx23885_buffer *buf) -{ - /* setup fifo + format */ - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], - buf->vb.width, buf->risc.dma); - - /* reset counter */ - q->count = 1; - - /* enable irqs */ - cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | 0x01); - cx_set(VID_A_INT_MSK, 0x000022); - - /* start dma */ - cx_set(DEV_CNTRL2, (1<<5)); - cx_set(VID_A_DMA_CTL, 0x00000022); - - return 0; -} - - -static int cx23885_restart_vbi_queue(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q) -{ - struct cx23885_buffer *buf; - struct list_head *item; - - if (list_empty(&q->active)) - return 0; - - buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); - dprintk(2, "restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); - cx23885_start_vbi_dma(dev, q, buf); - list_for_each(item, &q->active) { - buf = list_entry(item, struct cx23885_buffer, vb.queue); - buf->count = q->count++; - } - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - return 0; -} - -void cx23885_vbi_timeout(unsigned long data) -{ - struct cx23885_dev *dev = (struct cx23885_dev *)data; - struct cx23885_dmaqueue *q = &dev->vbiq; - struct cx23885_buffer *buf; - unsigned long flags; - - cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH02]); - - cx_clear(VID_A_DMA_CTL, 0x22); - - spin_lock_irqsave(&dev->slock, flags); - while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx23885_buffer, - vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->name, - buf, buf->vb.i, (unsigned long)buf->risc.dma); - } - cx23885_restart_vbi_queue(dev, q); - spin_unlock_irqrestore(&dev->slock, flags); -} - -/* ------------------------------------------------------------------ */ -#define VBI_LINE_LENGTH 2048 -#define VBI_LINE_COUNT 17 - -static int -vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) -{ - *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; - if (0 == *count) - *count = vbibufs; - if (*count < 2) - *count = 2; - if (*count > 32) - *count = 32; - return 0; -} - -static int -vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct cx23885_fh *fh = q->priv_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_buffer *buf = container_of(vb, - struct cx23885_buffer, vb); - struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); - unsigned int size; - int rc; - - size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; - if (0 != buf->vb.baddr && buf->vb.bsize < size) - return -EINVAL; - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - buf->vb.width = VBI_LINE_LENGTH; - buf->vb.height = VBI_LINE_COUNT; - buf->vb.size = size; - buf->vb.field = V4L2_FIELD_SEQ_TB; - - rc = videobuf_iolock(q, &buf->vb, NULL); - if (0 != rc) - goto fail; - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - 0, buf->vb.width * buf->vb.height, - buf->vb.width, 0, - buf->vb.height); - } - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - - fail: - cx23885_free_buffer(q, buf); - return rc; -} - -static void -vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct cx23885_buffer *buf = - container_of(vb, struct cx23885_buffer, vb); - struct cx23885_buffer *prev; - struct cx23885_fh *fh = vq->priv_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_dmaqueue *q = &dev->vbiq; - - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); - buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ - - if (list_empty(&q->active)) { - list_add_tail(&buf->vb.queue, &q->active); - cx23885_start_vbi_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2, "[%p/%d] vbi_queue - first active\n", - buf, buf->vb.i); - - } else { - prev = list_entry(q->active.prev, struct cx23885_buffer, - vb.queue); - list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63-32 */ - dprintk(2, "[%p/%d] buffer_queue - append to active\n", - buf, buf->vb.i); - } -} - -static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct cx23885_buffer *buf = - container_of(vb, struct cx23885_buffer, vb); - - cx23885_free_buffer(q, buf); -} - -struct videobuf_queue_ops cx23885_vbi_qops = { - .buf_setup = vbi_setup, - .buf_prepare = vbi_prepare, - .buf_queue = vbi_queue, - .buf_release = vbi_release, -}; - -/* ------------------------------------------------------------------ */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c deleted file mode 100644 index eaa11893bfe..00000000000 --- a/drivers/media/video/cx23885/cx23885-video.c +++ /dev/null @@ -1,1557 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2007 Steven Toth <stoth@linuxtv.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/init.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kmod.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/kthread.h> -#include <asm/div64.h> - -#include "cx23885.h" -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> - -#ifdef CONFIG_VIDEO_V4L1_COMPAT -/* Include V4L1 specific functions. Should be removed soon */ -#include <linux/videodev.h> -#endif - -MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); -MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------------ */ - -static unsigned int video_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; -static unsigned int vbi_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; -static unsigned int radio_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; - -module_param_array(video_nr, int, NULL, 0444); -module_param_array(vbi_nr, int, NULL, 0444); -module_param_array(radio_nr, int, NULL, 0444); - -MODULE_PARM_DESC(video_nr, "video device numbers"); -MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); -MODULE_PARM_DESC(radio_nr, "radio device numbers"); - -static unsigned int video_debug; -module_param(video_debug, int, 0644); -MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); - -static unsigned int irq_debug; -module_param(irq_debug, int, 0644); -MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); - -static unsigned int vid_limit = 16; -module_param(vid_limit, int, 0644); -MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); - -#define dprintk(level, fmt, arg...)\ - do { if (video_debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ - } while (0) - -/* ------------------------------------------------------------------- */ -/* static data */ - -#define FORMAT_FLAGS_PACKED 0x01 - -static struct cx23885_fmt formats[] = { - { - .name = "8 bpp, gray", - .fourcc = V4L2_PIX_FMT_GREY, - .depth = 8, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "15 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_RGB555, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "15 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB555X, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "16 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_RGB565, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "16 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB565X, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "24 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_BGR24, - .depth = 24, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "32 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_BGR32, - .depth = 32, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "32 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB32, - .depth = 32, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "4:2:2, packed, YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, -}; - -static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(formats); i++) - if (formats[i].fourcc == fourcc) - return formats+i; - - printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc); - return NULL; -} - -/* ------------------------------------------------------------------- */ - -static const struct v4l2_queryctrl no_ctl = { - .name = "42", - .flags = V4L2_CTRL_FLAG_DISABLED, -}; - -static struct cx23885_ctrl cx23885_ctls[] = { - /* --- video --- */ - { - .v = { - .id = V4L2_CID_BRIGHTNESS, - .name = "Brightness", - .minimum = 0x00, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 128, - .reg = LUMA_CTRL, - .mask = 0x00ff, - .shift = 0, - }, { - .v = { - .id = V4L2_CID_CONTRAST, - .name = "Contrast", - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x3f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 0, - .reg = LUMA_CTRL, - .mask = 0xff00, - .shift = 8, - }, { - .v = { - .id = V4L2_CID_HUE, - .name = "Hue", - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 128, - .reg = CHROMA_CTRL, - .mask = 0xff0000, - .shift = 16, - }, { - /* strictly, this only describes only U saturation. - * V saturation is handled specially through code. - */ - .v = { - .id = V4L2_CID_SATURATION, - .name = "Saturation", - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 0, - .reg = CHROMA_CTRL, - .mask = 0x00ff, - .shift = 0, - }, { - /* --- audio --- */ - .v = { - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .default_value = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - }, - .reg = PATH1_CTL1, - .mask = (0x1f << 24), - .shift = 24, - }, { - .v = { - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = 0, - .maximum = 0x3f, - .step = 1, - .default_value = 0x3f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .reg = PATH1_VOL_CTL, - .mask = 0xff, - .shift = 0, - } -}; -static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls); - -static const u32 cx23885_user_ctrls[] = { - V4L2_CID_USER_CLASS, - V4L2_CID_BRIGHTNESS, - V4L2_CID_CONTRAST, - V4L2_CID_SATURATION, - V4L2_CID_HUE, - V4L2_CID_AUDIO_VOLUME, - V4L2_CID_AUDIO_MUTE, - 0 -}; - -static const u32 *ctrl_classes[] = { - cx23885_user_ctrls, - NULL -}; - -static void cx23885_video_wakeup(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q, u32 count) -{ - struct cx23885_buffer *buf; - int bc; - - for (bc = 0;; bc++) { - if (list_empty(&q->active)) - break; - buf = list_entry(q->active.next, - struct cx23885_buffer, vb.queue); - - /* count comes from the hw and is is 16bit wide -- - * this trick handles wrap-arounds correctly for - * up to 32767 buffers in flight... */ - if ((s16) (count - buf->count) < 0) - break; - - do_gettimeofday(&buf->vb.ts); - dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, - count, buf->count); - buf->vb.state = VIDEOBUF_DONE; - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); - } - if (list_empty(&q->active)) - del_timer(&q->timeout); - else - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - if (bc != 1) - printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", - __func__, bc); -} - -static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) -{ - dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", - __func__, - (unsigned int)norm, - v4l2_norm_to_name(norm)); - - dev->tvnorm = norm; - - /* Tell the analog tuner/demods */ - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm); - - /* Tell the internal A/V decoder */ - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm); - - return 0; -} - -static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, - struct pci_dev *pci, - struct video_device *template, - char *type) -{ - struct video_device *vfd; - dprintk(1, "%s()\n", __func__); - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - *vfd = *template; - vfd->minor = -1; - vfd->parent = &pci->dev; - vfd->release = video_device_release; - snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", - dev->name, type, cx23885_boards[dev->board].name); - return vfd; -} - -static int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl) -{ - int i; - - if (qctrl->id < V4L2_CID_BASE || - qctrl->id >= V4L2_CID_LASTP1) - return -EINVAL; - for (i = 0; i < CX23885_CTLS; i++) - if (cx23885_ctls[i].v.id == qctrl->id) - break; - if (i == CX23885_CTLS) { - *qctrl = no_ctl; - return 0; - } - *qctrl = cx23885_ctls[i].v; - return 0; -} - -/* ------------------------------------------------------------------- */ -/* resource management */ - -static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, - unsigned int bit) -{ - dprintk(1, "%s()\n", __func__); - if (fh->resources & bit) - /* have it already allocated */ - return 1; - - /* is it free? */ - mutex_lock(&dev->lock); - if (dev->resources & bit) { - /* no, someone else uses it */ - mutex_unlock(&dev->lock); - return 0; - } - /* it's free, grab it */ - fh->resources |= bit; - dev->resources |= bit; - dprintk(1, "res: get %d\n", bit); - mutex_unlock(&dev->lock); - return 1; -} - -static int res_check(struct cx23885_fh *fh, unsigned int bit) -{ - return fh->resources & bit; -} - -static int res_locked(struct cx23885_dev *dev, unsigned int bit) -{ - return dev->resources & bit; -} - -static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, - unsigned int bits) -{ - BUG_ON((fh->resources & bits) != bits); - dprintk(1, "%s()\n", __func__); - - mutex_lock(&dev->lock); - fh->resources &= ~bits; - dev->resources &= ~bits; - dprintk(1, "res: put %d\n", bits); - mutex_unlock(&dev->lock); -} - -static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) -{ - struct v4l2_routing route; - memset(&route, 0, sizeof(route)); - - dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", - __func__, - input, INPUT(input)->vmux, - INPUT(input)->gpio0, INPUT(input)->gpio1, - INPUT(input)->gpio2, INPUT(input)->gpio3); - dev->input = input; - - route.input = INPUT(input)->vmux; - - /* Tell the internal A/V decoder */ - cx23885_call_i2c_clients(&dev->i2c_bus[2], - VIDIOC_INT_S_VIDEO_ROUTING, &route); - - return 0; -} - -/* ------------------------------------------------------------------ */ -static int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width, - unsigned int height, enum v4l2_field field) -{ - dprintk(1, "%s()\n", __func__); - return 0; -} - -static int cx23885_start_video_dma(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q, - struct cx23885_buffer *buf) -{ - dprintk(1, "%s()\n", __func__); - - /* setup fifo + format */ - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], - buf->bpl, buf->risc.dma); - cx23885_set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field); - - /* reset counter */ - cx_write(VID_A_GPCNT_CTL, 3); - q->count = 1; - - /* enable irq */ - cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | 0x01); - cx_set(VID_A_INT_MSK, 0x000011); - - /* start dma */ - cx_set(DEV_CNTRL2, (1<<5)); - cx_set(VID_A_DMA_CTL, 0x11); /* FIFO and RISC enable */ - - return 0; -} - - -static int cx23885_restart_video_queue(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q) -{ - struct cx23885_buffer *buf, *prev; - struct list_head *item; - dprintk(1, "%s()\n", __func__); - - if (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx23885_buffer, - vb.queue); - dprintk(2, "restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); - cx23885_start_video_dma(dev, q, buf); - list_for_each(item, &q->active) { - buf = list_entry(item, struct cx23885_buffer, - vb.queue); - buf->count = q->count++; - } - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - return 0; - } - - prev = NULL; - for (;;) { - if (list_empty(&q->queued)) - return 0; - buf = list_entry(q->queued.next, struct cx23885_buffer, - vb.queue); - if (NULL == prev) { - list_move_tail(&buf->vb.queue, &q->active); - cx23885_start_video_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2, "[%p/%d] restart_queue - first active\n", - buf, buf->vb.i); - - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_move_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */ - dprintk(2, "[%p/%d] restart_queue - move to active\n", - buf, buf->vb.i); - } else { - return 0; - } - prev = buf; - } -} - -static int buffer_setup(struct videobuf_queue *q, unsigned int *count, - unsigned int *size) -{ - struct cx23885_fh *fh = q->priv_data; - - *size = fh->fmt->depth*fh->width*fh->height >> 3; - if (0 == *count) - *count = 32; - while (*size * *count > vid_limit * 1024 * 1024) - (*count)--; - return 0; -} - -static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct cx23885_fh *fh = q->priv_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_buffer *buf = - container_of(vb, struct cx23885_buffer, vb); - int rc, init_buffer = 0; - u32 line0_offset, line1_offset; - struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); - - BUG_ON(NULL == fh->fmt); - if (fh->width < 48 || fh->width > norm_maxw(dev->tvnorm) || - fh->height < 32 || fh->height > norm_maxh(dev->tvnorm)) - return -EINVAL; - buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) - return -EINVAL; - - if (buf->fmt != fh->fmt || - buf->vb.width != fh->width || - buf->vb.height != fh->height || - buf->vb.field != field) { - buf->fmt = fh->fmt; - buf->vb.width = fh->width; - buf->vb.height = fh->height; - buf->vb.field = field; - init_buffer = 1; - } - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - init_buffer = 1; - rc = videobuf_iolock(q, &buf->vb, NULL); - if (0 != rc) - goto fail; - } - - if (init_buffer) { - buf->bpl = buf->vb.width * buf->fmt->depth >> 3; - switch (buf->vb.field) { - case V4L2_FIELD_TOP: - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, 0, UNSET, - buf->bpl, 0, buf->vb.height); - break; - case V4L2_FIELD_BOTTOM: - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, UNSET, 0, - buf->bpl, 0, buf->vb.height); - break; - case V4L2_FIELD_INTERLACED: - if (dev->tvnorm & V4L2_STD_NTSC) { - /* cx25840 transmits NTSC bottom field first */ - dprintk(1, "%s() Creating NTSC risc\n", - __func__); - line0_offset = buf->bpl; - line1_offset = 0; - } else { - /* All other formats are top field first */ - dprintk(1, "%s() Creating PAL/SECAM risc\n", - __func__); - line0_offset = 0; - line1_offset = buf->bpl; - } - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, line0_offset, - line1_offset, - buf->bpl, buf->bpl, - buf->vb.height >> 1); - break; - case V4L2_FIELD_SEQ_TB: - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - 0, buf->bpl * (buf->vb.height >> 1), - buf->bpl, 0, - buf->vb.height >> 1); - break; - case V4L2_FIELD_SEQ_BT: - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - buf->bpl * (buf->vb.height >> 1), 0, - buf->bpl, 0, - buf->vb.height >> 1); - break; - default: - BUG(); - } - } - dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", - buf, buf->vb.i, - fh->width, fh->height, fh->fmt->depth, fh->fmt->name, - (unsigned long)buf->risc.dma); - - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - - fail: - cx23885_free_buffer(q, buf); - return rc; -} - -static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct cx23885_buffer *buf = container_of(vb, - struct cx23885_buffer, vb); - struct cx23885_buffer *prev; - struct cx23885_fh *fh = vq->priv_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_dmaqueue *q = &dev->vidq; - - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); - buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ - - if (!list_empty(&q->queued)) { - list_add_tail(&buf->vb.queue, &q->queued); - buf->vb.state = VIDEOBUF_QUEUED; - dprintk(2, "[%p/%d] buffer_queue - append to queued\n", - buf, buf->vb.i); - - } else if (list_empty(&q->active)) { - list_add_tail(&buf->vb.queue, &q->active); - cx23885_start_video_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2, "[%p/%d] buffer_queue - first active\n", - buf, buf->vb.i); - - } else { - prev = list_entry(q->active.prev, struct cx23885_buffer, - vb.queue); - if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - /* 64 bit bits 63-32 */ - prev->risc.jmp[2] = cpu_to_le32(0); - dprintk(2, "[%p/%d] buffer_queue - append to active\n", - buf, buf->vb.i); - - } else { - list_add_tail(&buf->vb.queue, &q->queued); - buf->vb.state = VIDEOBUF_QUEUED; - dprintk(2, "[%p/%d] buffer_queue - first queued\n", - buf, buf->vb.i); - } - } -} - -static void buffer_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - struct cx23885_buffer *buf = container_of(vb, - struct cx23885_buffer, vb); - - cx23885_free_buffer(q, buf); -} - -static struct videobuf_queue_ops cx23885_video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, -}; - -static struct videobuf_queue *get_queue(struct cx23885_fh *fh) -{ - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return &fh->vidq; - case V4L2_BUF_TYPE_VBI_CAPTURE: - return &fh->vbiq; - default: - BUG(); - return NULL; - } -} - -static int get_resource(struct cx23885_fh *fh) -{ - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return RESOURCE_VIDEO; - case V4L2_BUF_TYPE_VBI_CAPTURE: - return RESOURCE_VBI; - default: - BUG(); - return 0; - } -} - -static int video_open(struct file *file) -{ - int minor = video_devdata(file)->minor; - struct cx23885_dev *h, *dev = NULL; - struct cx23885_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; - int radio = 0; - - lock_kernel(); - list_for_each(list, &cx23885_devlist) { - h = list_entry(list, struct cx23885_dev, devlist); - if (h->video_dev && - h->video_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - if (h->vbi_dev && - h->vbi_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VBI_CAPTURE; - } - if (h->radio_dev && - h->radio_dev->minor == minor) { - radio = 1; - dev = h; - } - } - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - - dprintk(1, "open minor=%d radio=%d type=%s\n", - minor, radio, v4l2_type_names[type]); - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); - return -ENOMEM; - } - file->private_data = fh; - fh->dev = dev; - fh->radio = radio; - fh->type = type; - fh->width = 320; - fh->height = 240; - fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); - - videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct cx23885_buffer), - fh); - - dprintk(1, "post videobuf_queue_init()\n"); - - unlock_kernel(); - - return 0; -} - -static ssize_t video_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct cx23885_fh *fh = file->private_data; - - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (res_locked(fh->dev, RESOURCE_VIDEO)) - return -EBUSY; - return videobuf_read_one(&fh->vidq, data, count, ppos, - file->f_flags & O_NONBLOCK); - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (!res_get(fh->dev, fh, RESOURCE_VBI)) - return -EBUSY; - return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1, - file->f_flags & O_NONBLOCK); - default: - BUG(); - return 0; - } -} - -static unsigned int video_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_buffer *buf; - - if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { - if (!res_get(fh->dev, fh, RESOURCE_VBI)) - return POLLERR; - return videobuf_poll_stream(file, &fh->vbiq, wait); - } - - if (res_check(fh, RESOURCE_VIDEO)) { - /* streaming capture */ - if (list_empty(&fh->vidq.stream)) - return POLLERR; - buf = list_entry(fh->vidq.stream.next, - struct cx23885_buffer, vb.stream); - } else { - /* read() capture */ - buf = (struct cx23885_buffer *)fh->vidq.read_buf; - if (NULL == buf) - return POLLERR; - } - poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == VIDEOBUF_DONE || - buf->vb.state == VIDEOBUF_ERROR) - return POLLIN|POLLRDNORM; - return 0; -} - -static int video_release(struct file *file) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - /* turn off overlay */ - if (res_check(fh, RESOURCE_OVERLAY)) { - /* FIXME */ - res_free(dev, fh, RESOURCE_OVERLAY); - } - - /* stop video capture */ - if (res_check(fh, RESOURCE_VIDEO)) { - videobuf_queue_cancel(&fh->vidq); - res_free(dev, fh, RESOURCE_VIDEO); - } - if (fh->vidq.read_buf) { - buffer_release(&fh->vidq, fh->vidq.read_buf); - kfree(fh->vidq.read_buf); - } - - /* stop vbi capture */ - if (res_check(fh, RESOURCE_VBI)) { - if (fh->vbiq.streaming) - videobuf_streamoff(&fh->vbiq); - if (fh->vbiq.reading) - videobuf_read_stop(&fh->vbiq); - res_free(dev, fh, RESOURCE_VBI); - } - - videobuf_mmap_free(&fh->vidq); - file->private_data = NULL; - kfree(fh); - - /* We are not putting the tuner to sleep here on exit, because - * we want to use the mpeg encoder in another session to capture - * tuner video. Closing this will result in no video to the encoder. - */ - - return 0; -} - -static int video_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_mmap_mapper(get_queue(fh), vma); -} - -/* ------------------------------------------------------------------ */ -/* VIDEO CTRL IOCTLS */ - -static int cx23885_get_control(struct cx23885_dev *dev, - struct v4l2_control *ctl) -{ - dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); - return 0; -} - -static int cx23885_set_control(struct cx23885_dev *dev, - struct v4l2_control *ctl) -{ - dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" - " (disabled - no action)\n", __func__); - return 0; -} - -static void init_controls(struct cx23885_dev *dev) -{ - struct v4l2_control ctrl; - int i; - - for (i = 0; i < CX23885_CTLS; i++) { - ctrl.id = cx23885_ctls[i].v.id; - ctrl.value = cx23885_ctls[i].v.default_value; - - cx23885_set_control(dev, &ctrl); - } -} - -/* ------------------------------------------------------------------ */ -/* VIDEO IOCTLS */ - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = priv; - - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; - f->fmt.pix.field = fh->vidq.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fh->fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - struct cx23885_fmt *fmt; - enum v4l2_field field; - unsigned int maxw, maxh; - - fmt = format_by_fourcc(f->fmt.pix.pixelformat); - if (NULL == fmt) - return -EINVAL; - - field = f->fmt.pix.field; - maxw = norm_maxw(dev->tvnorm); - maxh = norm_maxh(dev->tvnorm); - - if (V4L2_FIELD_ANY == field) { - field = (f->fmt.pix.height > maxh/2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - } - - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - break; - default: - return -EINVAL; - } - - f->fmt.pix.field = field; - if (f->fmt.pix.height < 32) - f->fmt.pix.height = 32; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - f->fmt.pix.width &= ~0x03; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - int err; - - dprintk(2, "%s()\n", __func__); - err = vidioc_try_fmt_vid_cap(file, priv, f); - - if (0 != err) - return err; - fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - fh->vidq.field = f->fmt.pix.field; - dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, - fh->width, fh->height, fh->vidq.field); - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f); - return 0; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - strcpy(cap->driver, "cx23885"); - strlcpy(cap->card, cx23885_boards[dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); - cap->version = CX23885_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING | - V4L2_CAP_VBI_CAPTURE; - if (UNSET != dev->tuner_type) - cap->capabilities |= V4L2_CAP_TUNER; - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (unlikely(f->index >= ARRAY_SIZE(formats))) - return -EINVAL; - - strlcpy(f->description, formats[f->index].name, - sizeof(f->description)); - f->pixelformat = formats[f->index].fourcc; - - return 0; -} - -#ifdef CONFIG_VIDEO_V4L1_COMPAT -static int vidiocgmbuf(struct file *file, void *priv, - struct video_mbuf *mbuf) -{ - struct cx23885_fh *fh = priv; - struct videobuf_queue *q; - struct v4l2_requestbuffers req; - unsigned int i; - int err; - - q = get_queue(fh); - memset(&req, 0, sizeof(req)); - req.type = q->type; - req.count = 8; - req.memory = V4L2_MEMORY_MMAP; - err = videobuf_reqbufs(q, &req); - if (err < 0) - return err; - - mbuf->frames = req.count; - mbuf->size = 0; - for (i = 0; i < mbuf->frames; i++) { - mbuf->offsets[i] = q->bufs[i]->boff; - mbuf->size += q->bufs[i]->bsize; - } - return 0; -} -#endif - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p) -{ - struct cx23885_fh *fh = priv; - return videobuf_reqbufs(get_queue(fh), p); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = priv; - return videobuf_querybuf(get_queue(fh), p); -} - -static int vidioc_qbuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = priv; - return videobuf_qbuf(get_queue(fh), p); -} - -static int vidioc_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = priv; - return videobuf_dqbuf(get_queue(fh), p, - file->f_flags & O_NONBLOCK); -} - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type i) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - dprintk(1, "%s()\n", __func__); - - if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) - return -EINVAL; - if (unlikely(i != fh->type)) - return -EINVAL; - - if (unlikely(!res_get(dev, fh, get_resource(fh)))) - return -EBUSY; - return videobuf_streamon(get_queue(fh)); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - int err, res; - dprintk(1, "%s()\n", __func__); - - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (i != fh->type) - return -EINVAL; - - res = get_resource(fh); - err = videobuf_streamoff(get_queue(fh)); - if (err < 0) - return err; - res_free(dev, fh, res); - return 0; -} - -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s()\n", __func__); - - mutex_lock(&dev->lock); - cx23885_set_tvnorm(dev, *tvnorms); - mutex_unlock(&dev->lock); - - return 0; -} - -static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) -{ - static const char *iname[] = { - [CX23885_VMUX_COMPOSITE1] = "Composite1", - [CX23885_VMUX_COMPOSITE2] = "Composite2", - [CX23885_VMUX_COMPOSITE3] = "Composite3", - [CX23885_VMUX_COMPOSITE4] = "Composite4", - [CX23885_VMUX_SVIDEO] = "S-Video", - [CX23885_VMUX_TELEVISION] = "Television", - [CX23885_VMUX_CABLE] = "Cable TV", - [CX23885_VMUX_DVB] = "DVB", - [CX23885_VMUX_DEBUG] = "for debug only", - }; - unsigned int n; - dprintk(1, "%s()\n", __func__); - - n = i->index; - if (n >= 4) - return -EINVAL; - - if (0 == INPUT(n)->type) - return -EINVAL; - - memset(i, 0, sizeof(*i)); - i->index = n; - i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name, iname[INPUT(n)->type]); - if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) || - (CX23885_VMUX_CABLE == INPUT(n)->type)) - i->type = V4L2_INPUT_TYPE_TUNER; - i->std = CX23885_NORMS; - return 0; -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s()\n", __func__); - return cx23885_enum_input(dev, i); -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - *i = dev->input; - dprintk(1, "%s() returns %d\n", __func__, *i); - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - dprintk(1, "%s(%d)\n", __func__, i); - - if (i >= 4) { - dprintk(1, "%s() -EINVAL\n", __func__); - return -EINVAL; - } - - mutex_lock(&dev->lock); - cx23885_video_mux(dev, i); - mutex_unlock(&dev->lock); - return 0; -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qctrl) -{ - qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); - if (unlikely(qctrl->id == 0)) - return -EINVAL; - return cx23885_ctrl_query(qctrl); -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - return cx23885_get_control(dev, ctl); -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - return cx23885_set_control(dev, ctl); -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - - strcpy(t->name, "Television"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM; - t->rangehigh = 0xffffffffUL; - t->signal = 0xffff ; /* LOCKED */ - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - if (UNSET == dev->tuner_type) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - - /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */ - f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - f->frequency = dev->freq; - - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f); - - return 0; -} - -static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) -{ - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - if (unlikely(f->tuner != 0)) - return -EINVAL; - - mutex_lock(&dev->lock); - dev->freq = f->frequency; - - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f); - - /* When changing channels it is required to reset TVAUDIO */ - msleep(10); - - mutex_unlock(&dev->lock); - - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)) - return -EINVAL; - if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) - return -EINVAL; - - return - cx23885_set_freq(dev, f); -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int vidioc_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; - - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg); - - return 0; -} - -static int vidioc_s_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; - - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg); - - return 0; -} -#endif - -/* ----------------------------------------------------------- */ - -static void cx23885_vid_timeout(unsigned long data) -{ - struct cx23885_dev *dev = (struct cx23885_dev *)data; - struct cx23885_dmaqueue *q = &dev->vidq; - struct cx23885_buffer *buf; - unsigned long flags; - - cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]); - - cx_clear(VID_A_DMA_CTL, 0x11); - - spin_lock_irqsave(&dev->slock, flags); - while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, - struct cx23885_buffer, vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - printk(KERN_ERR "%s/0: [%p/%d] timeout - dma=0x%08lx\n", - dev->name, buf, buf->vb.i, - (unsigned long)buf->risc.dma); - } - cx23885_restart_video_queue(dev, q); - spin_unlock_irqrestore(&dev->slock, flags); -} - -int cx23885_video_irq(struct cx23885_dev *dev, u32 status) -{ - u32 mask, count; - int handled = 0; - - mask = cx_read(VID_A_INT_MSK); - if (0 == (status & mask)) - return handled; - cx_write(VID_A_INT_STAT, status); - - dprintk(2, "%s() status = 0x%08x\n", __func__, status); - /* risc op code error */ - if (status & (1 << 16)) { - printk(KERN_WARNING "%s/0: video risc op code error\n", - dev->name); - cx_clear(VID_A_DMA_CTL, 0x11); - cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]); - } - - /* risc1 y */ - if (status & 0x01) { - spin_lock(&dev->slock); - count = cx_read(VID_A_GPCNT); - cx23885_video_wakeup(dev, &dev->vidq, count); - spin_unlock(&dev->slock); - handled++; - } - /* risc2 y */ - if (status & 0x10) { - dprintk(2, "stopper video\n"); - spin_lock(&dev->slock); - cx23885_restart_video_queue(dev, &dev->vidq); - spin_unlock(&dev->slock); - handled++; - } - - return handled; -} - -/* ----------------------------------------------------------- */ -/* exported stuff */ - -static const struct v4l2_file_operations video_fops = { - .owner = THIS_MODULE, - .open = video_open, - .release = video_release, - .read = video_read, - .poll = video_poll, - .mmap = video_mmap, - .ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops video_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_g_fmt_vbi_cap = cx23885_vbi_fmt, - .vidioc_try_fmt_vbi_cap = cx23885_vbi_fmt, - .vidioc_s_fmt_vbi_cap = cx23885_vbi_fmt, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, -#ifdef CONFIG_VIDEO_V4L1_COMPAT - .vidiocgmbuf = vidiocgmbuf, -#endif - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = vidioc_g_register, - .vidioc_s_register = vidioc_s_register, -#endif -}; - -static struct video_device cx23885_vbi_template; -static struct video_device cx23885_video_template = { - .name = "cx23885-video", - .fops = &video_fops, - .minor = -1, - .ioctl_ops = &video_ioctl_ops, - .tvnorms = CX23885_NORMS, - .current_norm = V4L2_STD_NTSC_M, -}; - -static const struct v4l2_file_operations radio_fops = { - .owner = THIS_MODULE, - .open = video_open, - .release = video_release, - .ioctl = video_ioctl2, -}; - - -void cx23885_video_unregister(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - cx_clear(PCI_INT_MSK, 1); - - if (dev->video_dev) { - if (-1 != dev->video_dev->minor) - video_unregister_device(dev->video_dev); - else - video_device_release(dev->video_dev); - dev->video_dev = NULL; - - btcx_riscmem_free(dev->pci, &dev->vidq.stopper); - } -} - -int cx23885_video_register(struct cx23885_dev *dev) -{ - int err; - - dprintk(1, "%s()\n", __func__); - spin_lock_init(&dev->slock); - - /* Initialize VBI template */ - memcpy(&cx23885_vbi_template, &cx23885_video_template, - sizeof(cx23885_vbi_template)); - strcpy(cx23885_vbi_template.name, "cx23885-vbi"); - - dev->tvnorm = cx23885_video_template.current_norm; - - /* init video dma queues */ - INIT_LIST_HEAD(&dev->vidq.active); - INIT_LIST_HEAD(&dev->vidq.queued); - dev->vidq.timeout.function = cx23885_vid_timeout; - dev->vidq.timeout.data = (unsigned long)dev; - init_timer(&dev->vidq.timeout); - cx23885_risc_stopper(dev->pci, &dev->vidq.stopper, - VID_A_DMA_CTL, 0x11, 0x00); - - /* Don't enable VBI yet */ - cx_set(PCI_INT_MSK, 1); - - - /* register v4l devices */ - dev->video_dev = cx23885_vdev_init(dev, dev->pci, - &cx23885_video_template, "video"); - err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, - video_nr[dev->nr]); - if (err < 0) { - printk(KERN_INFO "%s: can't register video device\n", - dev->name); - goto fail_unreg; - } - printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", - dev->name, dev->video_dev->num); - /* initial device configuration */ - mutex_lock(&dev->lock); - cx23885_set_tvnorm(dev, dev->tvnorm); - init_controls(dev); - cx23885_video_mux(dev, 0); - mutex_unlock(&dev->lock); - - return 0; - -fail_unreg: - cx23885_video_unregister(dev); - return err; -} - diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h deleted file mode 100644 index 67828029fc6..00000000000 --- a/drivers/media/video/cx23885/cx23885.h +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 Steven Toth <stoth@linuxtv.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/pci.h> -#include <linux/i2c.h> -#include <linux/i2c-algo-bit.h> -#include <linux/kdev_t.h> - -#include <media/v4l2-common.h> -#include <media/tuner.h> -#include <media/tveeprom.h> -#include <media/videobuf-dma-sg.h> -#include <media/videobuf-dvb.h> - -#include "btcx-risc.h" -#include "cx23885-reg.h" -#include "media/cx2341x.h" - -#include <linux/version.h> -#include <linux/mutex.h> - -#define CX23885_VERSION_CODE KERNEL_VERSION(0, 0, 1) - -#define UNSET (-1U) - -#define CX23885_MAXBOARDS 8 - -/* Max number of inputs by card */ -#define MAX_CX23885_INPUT 8 -#define INPUT(nr) (&cx23885_boards[dev->board].input[nr]) -#define RESOURCE_OVERLAY 1 -#define RESOURCE_VIDEO 2 -#define RESOURCE_VBI 4 - -#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ - -#define CX23885_BOARD_NOAUTO UNSET -#define CX23885_BOARD_UNKNOWN 0 -#define CX23885_BOARD_HAUPPAUGE_HVR1800lp 1 -#define CX23885_BOARD_HAUPPAUGE_HVR1800 2 -#define CX23885_BOARD_HAUPPAUGE_HVR1250 3 -#define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP 4 -#define CX23885_BOARD_HAUPPAUGE_HVR1500Q 5 -#define CX23885_BOARD_HAUPPAUGE_HVR1500 6 -#define CX23885_BOARD_HAUPPAUGE_HVR1200 7 -#define CX23885_BOARD_HAUPPAUGE_HVR1700 8 -#define CX23885_BOARD_HAUPPAUGE_HVR1400 9 -#define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10 -#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11 -#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12 -#define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13 - -/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ -#define CX23885_NORMS (\ - V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443 | \ - V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \ - V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \ - V4L2_STD_PAL_60 | V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK) - -struct cx23885_fmt { - char *name; - u32 fourcc; /* v4l2 format id */ - int depth; - int flags; - u32 cxformat; -}; - -struct cx23885_ctrl { - struct v4l2_queryctrl v; - u32 off; - u32 reg; - u32 mask; - u32 shift; -}; - -struct cx23885_tvnorm { - char *name; - v4l2_std_id id; - u32 cxiformat; - u32 cxoformat; -}; - -struct cx23885_fh { - struct cx23885_dev *dev; - enum v4l2_buf_type type; - int radio; - u32 resources; - - /* video overlay */ - struct v4l2_window win; - struct v4l2_clip *clips; - unsigned int nclips; - - /* video capture */ - struct cx23885_fmt *fmt; - unsigned int width, height; - - /* vbi capture */ - struct videobuf_queue vidq; - struct videobuf_queue vbiq; - - /* MPEG Encoder specifics ONLY */ - struct videobuf_queue mpegq; - atomic_t v4l_reading; -}; - -enum cx23885_itype { - CX23885_VMUX_COMPOSITE1 = 1, - CX23885_VMUX_COMPOSITE2, - CX23885_VMUX_COMPOSITE3, - CX23885_VMUX_COMPOSITE4, - CX23885_VMUX_SVIDEO, - CX23885_VMUX_TELEVISION, - CX23885_VMUX_CABLE, - CX23885_VMUX_DVB, - CX23885_VMUX_DEBUG, - CX23885_RADIO, -}; - -enum cx23885_src_sel_type { - CX23885_SRC_SEL_EXT_656_VIDEO = 0, - CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO -}; - -/* buffer for one video frame */ -struct cx23885_buffer { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - /* cx23885 specific */ - unsigned int bpl; - struct btcx_riscmem risc; - struct cx23885_fmt *fmt; - u32 count; -}; - -struct cx23885_input { - enum cx23885_itype type; - unsigned int vmux; - u32 gpio0, gpio1, gpio2, gpio3; -}; - -typedef enum { - CX23885_MPEG_UNDEFINED = 0, - CX23885_MPEG_DVB, - CX23885_ANALOG_VIDEO, - CX23885_MPEG_ENCODER, -} port_t; - -struct cx23885_board { - char *name; - port_t porta, portb, portc; - unsigned int tuner_type; - unsigned int radio_type; - unsigned char tuner_addr; - unsigned char radio_addr; - - /* Vendors can and do run the PCIe bridge at different - * clock rates, driven physically by crystals on the PCBs. - * The core has to accomodate this. This allows the user - * to add new boards with new frequencys. The value is - * expressed in Hz. - * - * The core framework will default this value based on - * current designs, but it can vary. - */ - u32 clk_freq; - struct cx23885_input input[MAX_CX23885_INPUT]; -}; - -struct cx23885_subid { - u16 subvendor; - u16 subdevice; - u32 card; -}; - -struct cx23885_i2c { - struct cx23885_dev *dev; - - int nr; - - /* i2c i/o */ - struct i2c_adapter i2c_adap; - struct i2c_algo_bit_data i2c_algo; - struct i2c_client i2c_client; - u32 i2c_rc; - - /* 885 registers used for raw addess */ - u32 i2c_period; - u32 reg_ctrl; - u32 reg_stat; - u32 reg_addr; - u32 reg_rdata; - u32 reg_wdata; -}; - -struct cx23885_dmaqueue { - struct list_head active; - struct list_head queued; - struct timer_list timeout; - struct btcx_riscmem stopper; - u32 count; -}; - -struct cx23885_tsport { - struct cx23885_dev *dev; - - int nr; - int sram_chno; - - struct videobuf_dvb_frontends frontends; - - /* dma queues */ - struct cx23885_dmaqueue mpegq; - u32 ts_packet_size; - u32 ts_packet_count; - - int width; - int height; - - spinlock_t slock; - - /* registers */ - u32 reg_gpcnt; - u32 reg_gpcnt_ctl; - u32 reg_dma_ctl; - u32 reg_lngth; - u32 reg_hw_sop_ctrl; - u32 reg_gen_ctrl; - u32 reg_bd_pkt_status; - u32 reg_sop_status; - u32 reg_fifo_ovfl_stat; - u32 reg_vld_misc; - u32 reg_ts_clk_en; - u32 reg_ts_int_msk; - u32 reg_ts_int_stat; - u32 reg_src_sel; - - /* Default register vals */ - int pci_irqmask; - u32 dma_ctl_val; - u32 ts_int_msk_val; - u32 gen_ctrl_val; - u32 ts_clk_en_val; - u32 src_sel_val; - u32 vld_misc_val; - u32 hw_sop_ctrl_val; - - /* Allow a single tsport to have multiple frontends */ - u32 num_frontends; -}; - -struct cx23885_dev { - struct list_head devlist; - atomic_t refcount; - - /* pci stuff */ - struct pci_dev *pci; - unsigned char pci_rev, pci_lat; - int pci_bus, pci_slot; - u32 __iomem *lmmio; - u8 __iomem *bmmio; - int pci_irqmask; - int hwrevision; - - /* This valud is board specific and is used to configure the - * AV core so we see nice clean and stable video and audio. */ - u32 clk_freq; - - /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ - struct cx23885_i2c i2c_bus[3]; - - int nr; - struct mutex lock; - - /* board details */ - unsigned int board; - char name[32]; - - struct cx23885_tsport ts1, ts2; - - /* sram configuration */ - struct sram_channel *sram_channels; - - enum { - CX23885_BRIDGE_UNDEFINED = 0, - CX23885_BRIDGE_885 = 885, - CX23885_BRIDGE_887 = 887, - } bridge; - - /* Analog video */ - u32 resources; - unsigned int input; - u32 tvaudio; - v4l2_std_id tvnorm; - unsigned int tuner_type; - unsigned char tuner_addr; - unsigned int radio_type; - unsigned char radio_addr; - unsigned int has_radio; - - /* V4l */ - u32 freq; - struct video_device *video_dev; - struct video_device *vbi_dev; - struct video_device *radio_dev; - - struct cx23885_dmaqueue vidq; - struct cx23885_dmaqueue vbiq; - spinlock_t slock; - - /* MPEG Encoder ONLY settings */ - u32 cx23417_mailbox; - struct cx2341x_mpeg_params mpeg_params; - struct video_device *v4l_device; - atomic_t v4l_reader_count; - struct cx23885_tvnorm encodernorm; - -}; - -extern struct list_head cx23885_devlist; - -#define SRAM_CH01 0 /* Video A */ -#define SRAM_CH02 1 /* VBI A */ -#define SRAM_CH03 2 /* Video B */ -#define SRAM_CH04 3 /* Transport via B */ -#define SRAM_CH05 4 /* VBI B */ -#define SRAM_CH06 5 /* Video C */ -#define SRAM_CH07 6 /* Transport via C */ -#define SRAM_CH08 7 /* Audio Internal A */ -#define SRAM_CH09 8 /* Audio Internal B */ -#define SRAM_CH10 9 /* Audio External */ -#define SRAM_CH11 10 /* COMB_3D_N */ -#define SRAM_CH12 11 /* Comb 3D N1 */ -#define SRAM_CH13 12 /* Comb 3D N2 */ -#define SRAM_CH14 13 /* MOE Vid */ -#define SRAM_CH15 14 /* MOE RSLT */ - -struct sram_channel { - char *name; - u32 cmds_start; - u32 ctrl_start; - u32 cdt; - u32 fifo_start;; - u32 fifo_size; - u32 ptr1_reg; - u32 ptr2_reg; - u32 cnt1_reg; - u32 cnt2_reg; - u32 jumponly; -}; - -/* ----------------------------------------------------------- */ - -#define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) -#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) - -#define cx_andor(reg, mask, value) \ - writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ - ((value) & (mask)), dev->lmmio+((reg)>>2)) - -#define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) -#define cx_clear(reg, bit) cx_andor((reg), (bit), 0) - -/* ----------------------------------------------------------- */ -/* cx23885-core.c */ - -extern int cx23885_sram_channel_setup(struct cx23885_dev *dev, - struct sram_channel *ch, - unsigned int bpl, u32 risc); - -extern void cx23885_sram_channel_dump(struct cx23885_dev *dev, - struct sram_channel *ch); - -extern int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, - u32 reg, u32 mask, u32 value); - -extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, - struct scatterlist *sglist, - unsigned int top_offset, unsigned int bottom_offset, - unsigned int bpl, unsigned int padding, unsigned int lines); - -void cx23885_cancel_buffers(struct cx23885_tsport *port); - -extern int cx23885_restart_queue(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q); - -extern void cx23885_wakeup(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q, u32 count); - - -/* ----------------------------------------------------------- */ -/* cx23885-cards.c */ -extern struct cx23885_board cx23885_boards[]; -extern const unsigned int cx23885_bcount; - -extern struct cx23885_subid cx23885_subids[]; -extern const unsigned int cx23885_idcount; - -extern int cx23885_tuner_callback(void *priv, int component, - int command, int arg); -extern void cx23885_card_list(struct cx23885_dev *dev); -extern int cx23885_ir_init(struct cx23885_dev *dev); -extern void cx23885_gpio_setup(struct cx23885_dev *dev); -extern void cx23885_card_setup(struct cx23885_dev *dev); -extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev); - -extern int cx23885_dvb_register(struct cx23885_tsport *port); -extern int cx23885_dvb_unregister(struct cx23885_tsport *port); - -extern int cx23885_buf_prepare(struct videobuf_queue *q, - struct cx23885_tsport *port, - struct cx23885_buffer *buf, - enum v4l2_field field); -extern void cx23885_buf_queue(struct cx23885_tsport *port, - struct cx23885_buffer *buf); -extern void cx23885_free_buffer(struct videobuf_queue *q, - struct cx23885_buffer *buf); - -/* ----------------------------------------------------------- */ -/* cx23885-video.c */ -/* Video */ -extern int cx23885_video_register(struct cx23885_dev *dev); -extern void cx23885_video_unregister(struct cx23885_dev *dev); -extern int cx23885_video_irq(struct cx23885_dev *dev, u32 status); - -/* ----------------------------------------------------------- */ -/* cx23885-vbi.c */ -extern int cx23885_vbi_fmt(struct file *file, void *priv, - struct v4l2_format *f); -extern void cx23885_vbi_timeout(unsigned long data); -extern struct videobuf_queue_ops cx23885_vbi_qops; - -/* cx23885-i2c.c */ -extern int cx23885_i2c_register(struct cx23885_i2c *bus); -extern int cx23885_i2c_unregister(struct cx23885_i2c *bus); -extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd, - void *arg); -extern void cx23885_av_clk(struct cx23885_dev *dev, int enable); - -/* ----------------------------------------------------------- */ -/* cx23885-417.c */ -extern int cx23885_417_register(struct cx23885_dev *dev); -extern void cx23885_417_unregister(struct cx23885_dev *dev); -extern int cx23885_irq_417(struct cx23885_dev *dev, u32 status); -extern void cx23885_417_check_encoder(struct cx23885_dev *dev); -extern void cx23885_mc417_init(struct cx23885_dev *dev); -extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); -extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); - - -/* ----------------------------------------------------------- */ -/* tv norms */ - -static inline unsigned int norm_maxw(v4l2_std_id norm) -{ - return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768; -} - -static inline unsigned int norm_maxh(v4l2_std_id norm) -{ - return (norm & V4L2_STD_625_50) ? 576 : 480; -} - -static inline unsigned int norm_swidth(v4l2_std_id norm) -{ - return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; -} |
