⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 saa7115.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/* saa711x - Philips SAA711x video decoder driver * This driver can work with saa7111, saa7111a, saa7113, saa7114, *			     saa7115 and saa7118. * * Based on saa7114 driver by Maxim Yevtyushkin, which is based on * the saa7111 driver by Dave Perks. * * Copyright (C) 1998 Dave Perks <dperks@ibm.net> * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com> * * Slight changes for video timing and attachment output by * Wolfgang Scherr <scherr@net4you.net> * * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003) * by Ronald Bultje <rbultje@ronald.bitfreak.net> * * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com> * (2/17/2003) * * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> * * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> *	SAA7111, SAA7113 and SAA7118 support * * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. */#include "saa711x_regs.h"#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/i2c.h>#include <linux/videodev2.h>#include <media/v4l2-common.h>#include <media/v4l2-chip-ident.h>#include <media/v4l2-i2c-drv-legacy.h>#include <media/saa7115.h>#include <asm/div64.h>#include "compat.h"#define VRES_60HZ	(480+16)MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");MODULE_AUTHOR(  "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "		"Hans Verkuil, Mauro Carvalho Chehab");MODULE_LICENSE("GPL");static int debug;module_param(debug, bool, 0644);MODULE_PARM_DESC(debug, "Debug level (0-1)");static unsigned short normal_i2c[] = {		0x4a >> 1, 0x48 >> 1,	/* SAA7111, SAA7111A and SAA7113 */		0x42 >> 1, 0x40 >> 1,	/* SAA7114, SAA7115 and SAA7118 */		I2C_CLIENT_END };I2C_CLIENT_INSMOD;struct saa711x_state {	v4l2_std_id std;	int input;	int output;	int enable;	int radio;	int bright;	int contrast;	int hue;	int sat;	int width;	int height;	u32 ident;	u32 audclk_freq;	u32 crystal_freq;	u8 ucgc;	u8 cgcdiv;	u8 apll;};/* ----------------------------------------------------------------------- */static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value){	return i2c_smbus_write_byte_data(client, reg, value);}/* Sanity routine to check if a register is present */static int saa711x_has_reg(const int id, const u8 reg){	if (id == V4L2_IDENT_SAA7111)		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&		       (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;	/* common for saa7113/4/5/8 */	if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||	    reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||	    reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||	    reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))		return 0;	switch (id) {	case V4L2_IDENT_SAA7113:		return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&		       reg != 0x5d && reg < 0x63;	case V4L2_IDENT_SAA7114:		return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&		       (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&		       reg != 0x81 && reg < 0xf0;	case V4L2_IDENT_SAA7115:		return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);	case V4L2_IDENT_SAA7118:		return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&		       (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&		       (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;	}	return 1;}static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs){	struct saa711x_state *state = i2c_get_clientdata(client);	unsigned char reg, data;	while (*regs != 0x00) {		reg = *(regs++);		data = *(regs++);		/* According with datasheets, reserved regs should be		   filled with 0 - seems better not to touch on they */		if (saa711x_has_reg(state->ident,reg)) {			if (saa711x_write(client, reg, data) < 0)				return -1;		} else {			v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg);		}	}	return 0;}static inline int saa711x_read(struct i2c_client *client, u8 reg){	return i2c_smbus_read_byte_data(client, reg);}/* ----------------------------------------------------------------------- *//* SAA7111 initialization table */static const unsigned char saa7111_init[] = {	R_01_INC_DELAY, 0x00,		/* reserved */	/*front end */	R_02_INPUT_CNTL_1, 0xd0,	/* FUSE=3, GUDL=2, MODE=0 */	R_03_INPUT_CNTL_2, 0x23,	/* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,					 * GAFIX=0, GAI1=256, GAI2=256 */	R_04_INPUT_CNTL_3, 0x00,	/* GAI1=256 */	R_05_INPUT_CNTL_4, 0x00,	/* GAI2=256 */	/* decoder */	R_06_H_SYNC_START, 0xf3,	/* HSB at  13(50Hz) /  17(60Hz)					 * pixels after end of last line */	R_07_H_SYNC_STOP, 0xe8,		/* HSS seems to be needed to					 * work with NTSC, too */	R_08_SYNC_CNTL, 0xc8,		/* AUFD=1, FSEL=1, EXFIL=0,					 * VTRC=1, HPLL=0, VNOI=0 */	R_09_LUMA_CNTL, 0x01,		/* BYPS=0, PREF=0, BPSS=0,					 * VBLB=0, UPTCV=0, APER=1 */	R_0A_LUMA_BRIGHT_CNTL, 0x80,	R_0B_LUMA_CONTRAST_CNTL, 0x47,	/* 0b - CONT=1.109 */	R_0C_CHROMA_SAT_CNTL, 0x40,	R_0D_CHROMA_HUE_CNTL, 0x00,	R_0E_CHROMA_CNTL_1, 0x01,	/* 0e - CDTO=0, CSTD=0, DCCF=0,					 * FCTC=0, CHBW=1 */	R_0F_CHROMA_GAIN_CNTL, 0x00,	/* reserved */	R_10_CHROMA_CNTL_2, 0x48,	/* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */	R_11_MODE_DELAY_CNTL, 0x1c,	/* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,					 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */	R_12_RT_SIGNAL_CNTL, 0x00,	/* 12 - output control 2 */	R_13_RT_X_PORT_OUT_CNTL, 0x00,	/* 13 - output control 3 */	R_14_ANAL_ADC_COMPAT_CNTL, 0x00,	R_15_VGATE_START_FID_CHG, 0x00,	R_16_VGATE_STOP, 0x00,	R_17_MISC_VGATE_CONF_AND_MSB, 0x00,	0x00, 0x00};/* SAA7113 init codes */static const unsigned char saa7113_init[] = {	R_01_INC_DELAY, 0x08,	R_02_INPUT_CNTL_1, 0xc2,	R_03_INPUT_CNTL_2, 0x30,	R_04_INPUT_CNTL_3, 0x00,	R_05_INPUT_CNTL_4, 0x00,	R_06_H_SYNC_START, 0x89,	R_07_H_SYNC_STOP, 0x0d,	R_08_SYNC_CNTL, 0x88,	R_09_LUMA_CNTL, 0x01,	R_0A_LUMA_BRIGHT_CNTL, 0x80,	R_0B_LUMA_CONTRAST_CNTL, 0x47,	R_0C_CHROMA_SAT_CNTL, 0x40,	R_0D_CHROMA_HUE_CNTL, 0x00,	R_0E_CHROMA_CNTL_1, 0x01,	R_0F_CHROMA_GAIN_CNTL, 0x2a,	R_10_CHROMA_CNTL_2, 0x08,	R_11_MODE_DELAY_CNTL, 0x0c,	R_12_RT_SIGNAL_CNTL, 0x07,	R_13_RT_X_PORT_OUT_CNTL, 0x00,	R_14_ANAL_ADC_COMPAT_CNTL, 0x00,	R_15_VGATE_START_FID_CHG, 0x00,	R_16_VGATE_STOP, 0x00,	R_17_MISC_VGATE_CONF_AND_MSB, 0x00,	0x00, 0x00};/* If a value differs from the Hauppauge driver values, then the comment starts with   'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the   Hauppauge driver sets. *//* SAA7114 and SAA7115 initialization table */static const unsigned char saa7115_init_auto_input[] = {		/* Front-End Part */	R_01_INC_DELAY, 0x48,			/* white peak control disabled */	R_03_INPUT_CNTL_2, 0x20,		/* was 0x30. 0x20: long vertical blanking */	R_04_INPUT_CNTL_3, 0x90,		/* analog gain set to 0 */	R_05_INPUT_CNTL_4, 0x90,		/* analog gain set to 0 */		/* Decoder Part */	R_06_H_SYNC_START, 0xeb,		/* horiz sync begin = -21 */	R_07_H_SYNC_STOP, 0xe0,			/* horiz sync stop = -17 */	R_09_LUMA_CNTL, 0x53,			/* 0x53, was 0x56 for 60hz. luminance control */	R_0A_LUMA_BRIGHT_CNTL, 0x80,		/* was 0x88. decoder brightness, 0x80 is itu standard */	R_0B_LUMA_CONTRAST_CNTL, 0x44,		/* was 0x48. decoder contrast, 0x44 is itu standard */	R_0C_CHROMA_SAT_CNTL, 0x40,		/* was 0x47. decoder saturation, 0x40 is itu standard */	R_0D_CHROMA_HUE_CNTL, 0x00,	R_0F_CHROMA_GAIN_CNTL, 0x00,		/* use automatic gain  */	R_10_CHROMA_CNTL_2, 0x06,		/* chroma: active adaptive combfilter */	R_11_MODE_DELAY_CNTL, 0x00,	R_12_RT_SIGNAL_CNTL, 0x9d,		/* RTS0 output control: VGATE */	R_13_RT_X_PORT_OUT_CNTL, 0x80,		/* ITU656 standard mode, RTCO output enable RTCE */	R_14_ANAL_ADC_COMPAT_CNTL, 0x00,	R_18_RAW_DATA_GAIN_CNTL, 0x40,		/* gain 0x00 = nominal */	R_19_RAW_DATA_OFF_CNTL, 0x80,	R_1A_COLOR_KILL_LVL_CNTL, 0x77,		/* recommended value */	R_1B_MISC_TVVCRDET, 0x42,		/* recommended value */	R_1C_ENHAN_COMB_CTRL1, 0xa9,		/* recommended value */	R_1D_ENHAN_COMB_CTRL2, 0x01,		/* recommended value */	R_80_GLOBAL_CNTL_1, 0x0,		/* No tasks enabled at init */		/* Power Device Control */	R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,	/* reset device */	R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,	/* set device programmed, all in operational mode */	0x00, 0x00};/* Used to reset saa7113, saa7114 and saa7115 */static const unsigned char saa7115_cfg_reset_scaler[] = {	R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,	/* disable I-port output */	R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,		/* reset scaler */	R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,		/* activate scaler */	R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,	/* enable I-port output */	0x00, 0x00};/* ============== SAA7715 VIDEO templates =============  */static const unsigned char saa7115_cfg_60hz_video[] = {	R_80_GLOBAL_CNTL_1, 0x00,			/* reset tasks */	R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,		/* reset scaler */	R_15_VGATE_START_FID_CHG, 0x03,	R_16_VGATE_STOP, 0x11,	R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,	R_08_SYNC_CNTL, 0x68,			/* 0xBO: auto detection, 0x68 = NTSC */	R_0E_CHROMA_CNTL_1, 0x07,		/* video autodetection is on */	R_5A_V_OFF_FOR_SLICER, 0x06,		/* standard 60hz value for ITU656 line counting */	/* Task A */	R_90_A_TASK_HANDLING_CNTL, 0x80,	R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,	R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,	R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,	/* hoffset low (input), 0x0002 is minimum */	R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,	R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,	/* hsize low (input), 0x02d0 = 720 */	R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,	R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,	R_98_A_VERT_INPUT_WINDOW_START, 0x05,	R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,	R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,	R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,	R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,	R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,	R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,	R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,	/* Task B */	R_C0_B_TASK_HANDLING_CNTL, 0x00,	R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,	R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,	R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,	/* 0x0002 is minimum */	R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,	R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,	/* 0x02d0 = 720 */	R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,	R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,	/* vwindow start 0x12 = 18 */	R_C8_B_VERT_INPUT_WINDOW_START, 0x12,	R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,	/* vwindow length 0xf8 = 248 */	R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,	R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,	/* hwindow 0x02d0 = 720 */	R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,	R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,	R_F0_LFCO_PER_LINE, 0xad,		/* Set PLL Register. 60hz 525 lines per frame, 27 MHz */	R_F1_P_I_PARAM_SELECT, 0x05,		/* low bit with 0xF0 */	R_F5_PULSGEN_LINE_LENGTH, 0xad,	R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,	0x00, 0x00};static const unsigned char saa7115_cfg_50hz_video[] = {	R_80_GLOBAL_CNTL_1, 0x00,	R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,	/* reset scaler */	R_15_VGATE_START_FID_CHG, 0x37,		/* VGATE start */	R_16_VGATE_STOP, 0x16,	R_17_MISC_VGATE_CONF_AND_MSB, 0x99,	R_08_SYNC_CNTL, 0x28,			/* 0x28 = PAL */	R_0E_CHROMA_CNTL_1, 0x07,	R_5A_V_OFF_FOR_SLICER, 0x03,		/* standard 50hz value */	/* Task A */	R_90_A_TASK_HANDLING_CNTL, 0x81,	R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,	R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,	R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,	/* This is weird: the datasheet says that you should use 2 as the minimum value, */	/* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */	/* hoffset low (input), 0x0002 is minimum */	R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,	R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,	/* hsize low (input), 0x02d0 = 720 */	R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,	R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,	R_98_A_VERT_INPUT_WINDOW_START, 0x03,	R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,	/* vsize 0x12 = 18 */	R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,	R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,	/* hsize 0x05a0 = 1440 */	R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,	R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,	/* hsize hi (output) */	R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12,		/* vsize low (output), 0x12 = 18 */	R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,	/* vsize hi (output) */	/* Task B */	R_C0_B_TASK_HANDLING_CNTL, 0x00,	R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,	R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,	R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,	/* This is weird: the datasheet says that you should use 2 as the minimum value, */	/* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */	/* hoffset low (input), 0x0002 is minimum. See comment above. */	R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -