saa717x.c

来自「trident tm5600的linux驱动」· C语言 代码 · 共 1,535 行 · 第 1/3 页

C
1,535
字号
/* * saa717x - Philips SAA717xHL video decoder driver * * Based on the saa7115 driver * * Changes by Ohta Kyuma <alpha292@bremen.or.jp> *    - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004) * * Changes by T.Adachi (tadachi@tadachi-net.com) *    - support audio, video scaler etc, and checked the initialize sequence. * * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl> * * Note: this is a reversed engineered driver based on captures from * the I2C bus under Windows. This chip is very similar to the saa7134, * though. Unfortunately, this driver is currently only working for NTSC. * * 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/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/videodev2.h>#include <linux/i2c.h>#include <media/v4l2-common.h>#include <media/v4l2-i2c-drv.h>#include "compat.h"MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver");MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil");MODULE_LICENSE("GPL");static int debug;module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Debug level (0-1)");/* * Generic i2c probe * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)static unsigned short normal_i2c[] = { 0x42 >> 1, I2C_CLIENT_END };I2C_CLIENT_INSMOD;#endifstruct saa717x_state {	v4l2_std_id std;	int input;	int enable;	int radio;	int bright;	int contrast;	int hue;	int sat;	int playback;	int audio;	int tuner_audio_mode;	int audio_main_mute;	int audio_main_vol_r;	int audio_main_vol_l;	u16 audio_main_bass;	u16 audio_main_treble;	u16 audio_main_volume;	u16 audio_main_balance;	int audio_input;};/* ----------------------------------------------------------------------- *//* for audio mode */#define TUNER_AUDIO_MONO   	0  /* LL */#define TUNER_AUDIO_STEREO 	1  /* LR */#define TUNER_AUDIO_LANG1  	2  /* LL */#define TUNER_AUDIO_LANG2  	3  /* RR */#define SAA717X_NTSC_WIDTH   	(704)#define SAA717X_NTSC_HEIGHT  	(480)/* ----------------------------------------------------------------------- */static int saa717x_write(struct i2c_client *client, u32 reg, u32 value){	struct i2c_adapter *adap = client->adapter;	int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488;	unsigned char mm1[6];	struct i2c_msg msg;	msg.flags = 0;	msg.addr = client->addr;	mm1[0] = (reg >> 8) & 0xff;	mm1[1] = reg & 0xff;	if (fw_addr) {		mm1[4] = (value >> 16) & 0xff;		mm1[3] = (value >> 8) & 0xff;		mm1[2] = value & 0xff;	} else {		mm1[2] = value & 0xff;	}	msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */	msg.buf = mm1;	v4l_dbg(2, debug, client, "wrote:  reg 0x%03x=%08x\n", reg, value);	return i2c_transfer(adap, &msg, 1) == 1;}static void saa717x_write_regs(struct i2c_client *client, u32 *data){	while (data[0] || data[1]) {		saa717x_write(client, data[0], data[1]);		data += 2;	}}static u32 saa717x_read(struct i2c_client *client, u32 reg){	struct i2c_adapter *adap = client->adapter;	int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528;	unsigned char mm1[2];	unsigned char mm2[4] = { 0, 0, 0, 0 };	struct i2c_msg msgs[2];	u32 value;	msgs[0].flags = 0;	msgs[1].flags = I2C_M_RD;	msgs[0].addr = msgs[1].addr = client->addr;	mm1[0] = (reg >> 8) & 0xff;	mm1[1] = reg & 0xff;	msgs[0].len = 2;	msgs[0].buf = mm1;	msgs[1].len = fw_addr ? 3 : 1; /* Multibyte Registers contains *only* 3 bytes */	msgs[1].buf = mm2;	i2c_transfer(adap, msgs, 2);	if (fw_addr)		value = (mm2[2] & 0xff)  | ((mm2[1] & 0xff) >> 8) | ((mm2[0] & 0xff) >> 16);	else		value = mm2[0] & 0xff;	v4l_dbg(2, debug, client, "read:  reg 0x%03x=0x%08x\n", reg, value);	return value;}/* ----------------------------------------------------------------------- */static u32 reg_init_initialize[] ={	/* from linux driver */	0x101, 0x008, /* Increment delay */	0x103, 0x000, /* Analog input control 2 */	0x104, 0x090, /* Analog input control 3 */	0x105, 0x090, /* Analog input control 4 */	0x106, 0x0eb, /* Horizontal sync start */	0x107, 0x0e0, /* Horizontal sync stop */	0x109, 0x055, /* Luminance control */	0x10f, 0x02a, /* Chroma gain control */	0x110, 0x000, /* Chroma control 2 */	0x114, 0x045, /* analog/ADC */	0x118, 0x040, /* RAW data gain */	0x119, 0x080, /* RAW data offset */	0x044, 0x000, /* VBI horizontal input window start (L) TASK A */	0x045, 0x000, /* VBI horizontal input window start (H) TASK A */	0x046, 0x0cf, /* VBI horizontal input window stop (L) TASK A */	0x047, 0x002, /* VBI horizontal input window stop (H) TASK A */	0x049, 0x000, /* VBI vertical input window start (H) TASK A */	0x04c, 0x0d0, /* VBI horizontal output length (L) TASK A */	0x04d, 0x002, /* VBI horizontal output length (H) TASK A */	0x064, 0x080, /* Lumina brightness TASK A */	0x065, 0x040, /* Luminance contrast TASK A */	0x066, 0x040, /* Chroma saturation TASK A */	/* 067H: Reserved */	0x068, 0x000, /* VBI horizontal scaling increment (L) TASK A */	0x069, 0x004, /* VBI horizontal scaling increment (H) TASK A */	0x06a, 0x000, /* VBI phase offset TASK A */	0x06e, 0x000, /* Horizontal phase offset Luma TASK A */	0x06f, 0x000, /* Horizontal phase offset Chroma TASK A */	0x072, 0x000, /* Vertical filter mode TASK A */	0x084, 0x000, /* VBI horizontal input window start (L) TAKS B */	0x085, 0x000, /* VBI horizontal input window start (H) TAKS B */	0x086, 0x0cf, /* VBI horizontal input window stop (L) TAKS B */	0x087, 0x002, /* VBI horizontal input window stop (H) TAKS B */	0x089, 0x000, /* VBI vertical input window start (H) TAKS B */	0x08c, 0x0d0, /* VBI horizontal output length (L) TASK B */	0x08d, 0x002, /* VBI horizontal output length (H) TASK B */	0x0a4, 0x080, /* Lumina brightness TASK B */	0x0a5, 0x040, /* Luminance contrast TASK B */	0x0a6, 0x040, /* Chroma saturation TASK B */	/* 0A7H reserved */	0x0a8, 0x000, /* VBI horizontal scaling increment (L) TASK B */	0x0a9, 0x004, /* VBI horizontal scaling increment (H) TASK B */	0x0aa, 0x000, /* VBI phase offset TASK B */	0x0ae, 0x000, /* Horizontal phase offset Luma TASK B */	0x0af, 0x000, /*Horizontal phase offset Chroma TASK B */	0x0b2, 0x000, /* Vertical filter mode TASK B */	0x00c, 0x000, /* Start point GREEN path */	0x00d, 0x000, /* Start point BLUE path */	0x00e, 0x000, /* Start point RED path */	0x010, 0x010, /* GREEN path gamma curve --- */	0x011, 0x020,	0x012, 0x030,	0x013, 0x040,	0x014, 0x050,	0x015, 0x060,	0x016, 0x070,	0x017, 0x080,	0x018, 0x090,	0x019, 0x0a0,	0x01a, 0x0b0,	0x01b, 0x0c0,	0x01c, 0x0d0,	0x01d, 0x0e0,	0x01e, 0x0f0,	0x01f, 0x0ff, /* --- GREEN path gamma curve */	0x020, 0x010, /* BLUE path gamma curve --- */	0x021, 0x020,	0x022, 0x030,	0x023, 0x040,	0x024, 0x050,	0x025, 0x060,	0x026, 0x070,	0x027, 0x080,	0x028, 0x090,	0x029, 0x0a0,	0x02a, 0x0b0,	0x02b, 0x0c0,	0x02c, 0x0d0,	0x02d, 0x0e0,	0x02e, 0x0f0,	0x02f, 0x0ff, /* --- BLUE path gamma curve */	0x030, 0x010, /* RED path gamma curve --- */	0x031, 0x020,	0x032, 0x030,	0x033, 0x040,	0x034, 0x050,	0x035, 0x060,	0x036, 0x070,	0x037, 0x080,	0x038, 0x090,	0x039, 0x0a0,	0x03a, 0x0b0,	0x03b, 0x0c0,	0x03c, 0x0d0,	0x03d, 0x0e0,	0x03e, 0x0f0,	0x03f, 0x0ff, /* --- RED path gamma curve */	0x109, 0x085, /* Luminance control  */	/**** from app start ****/	0x584, 0x000, /* AGC gain control */	0x585, 0x000, /* Program count */	0x586, 0x003, /* Status reset */	0x588, 0x0ff, /* Number of audio samples (L) */	0x589, 0x00f, /* Number of audio samples (M) */	0x58a, 0x000, /* Number of audio samples (H) */	0x58b, 0x000, /* Audio select */	0x58c, 0x010, /* Audio channel assign1 */	0x58d, 0x032, /* Audio channel assign2 */	0x58e, 0x054, /* Audio channel assign3 */	0x58f, 0x023, /* Audio format */	0x590, 0x000, /* SIF control */	0x595, 0x000, /* ?? */	0x596, 0x000, /* ?? */	0x597, 0x000, /* ?? */	0x464, 0x00, /* Digital input crossbar1 */	0x46c, 0xbbbb10, /* Digital output selection1-3 */	0x470, 0x101010, /* Digital output selection4-6 */	0x478, 0x00, /* Sound feature control */	0x474, 0x18, /* Softmute control */	0x454, 0x0425b9, /* Sound Easy programming(reset) */	0x454, 0x042539, /* Sound Easy programming(reset) */	/**** common setting( of DVD play, including scaler commands) ****/	0x042, 0x003, /* Data path configuration for VBI (TASK A) */	0x082, 0x003, /* Data path configuration for VBI (TASK B) */	0x108, 0x0f8, /* Sync control */	0x2a9, 0x0fd, /* ??? */	0x102, 0x089, /* select video input "mode 9" */	0x111, 0x000, /* Mode/delay control */	0x10e, 0x00a, /* Chroma control 1 */	0x594, 0x002, /* SIF, analog I/O select */	0x454, 0x0425b9, /* Sound  */	0x454, 0x042539,	0x111, 0x000,	0x10e, 0x00a,	0x464, 0x000,	0x300, 0x000,	0x301, 0x006,	0x302, 0x000,	0x303, 0x006,	0x308, 0x040,	0x309, 0x000,	0x30a, 0x000,	0x30b, 0x000,	0x000, 0x002,	0x001, 0x000,	0x002, 0x000,	0x003, 0x000,	0x004, 0x033,	0x040, 0x01d,	0x041, 0x001,	0x042, 0x004,	0x043, 0x000,	0x080, 0x01e,	0x081, 0x001,	0x082, 0x004,	0x083, 0x000,	0x190, 0x018,	0x115, 0x000,	0x116, 0x012,	0x117, 0x018,	0x04a, 0x011,	0x08a, 0x011,	0x04b, 0x000,	0x08b, 0x000,	0x048, 0x000,	0x088, 0x000,	0x04e, 0x012,	0x08e, 0x012,	0x058, 0x012,	0x098, 0x012,	0x059, 0x000,	0x099, 0x000,	0x05a, 0x003,	0x09a, 0x003,	0x05b, 0x001,	0x09b, 0x001,	0x054, 0x008,	0x094, 0x008,	0x055, 0x000,	0x095, 0x000,	0x056, 0x0c7,	0x096, 0x0c7,	0x057, 0x002,	0x097, 0x002,	0x0ff, 0x0ff,	0x060, 0x001,	0x0a0, 0x001,	0x061, 0x000,	0x0a1, 0x000,	0x062, 0x000,	0x0a2, 0x000,	0x063, 0x000,	0x0a3, 0x000,	0x070, 0x000,	0x0b0, 0x000,	0x071, 0x004,	0x0b1, 0x004,	0x06c, 0x0e9,	0x0ac, 0x0e9,	0x06d, 0x003,	0x0ad, 0x003,	0x05c, 0x0d0,	0x09c, 0x0d0,	0x05d, 0x002,	0x09d, 0x002,	0x05e, 0x0f2,	0x09e, 0x0f2,	0x05f, 0x000,	0x09f, 0x000,	0x074, 0x000,	0x0b4, 0x000,	0x075, 0x000,	0x0b5, 0x000,	0x076, 0x000,	0x0b6, 0x000,	0x077, 0x000,	0x0b7, 0x000,	0x195, 0x008,	0x0ff, 0x0ff,	0x108, 0x0f8,	0x111, 0x000,	0x10e, 0x00a,	0x2a9, 0x0fd,	0x464, 0x001,	0x454, 0x042135,	0x598, 0x0e7,	0x599, 0x07d,	0x59a, 0x018,	0x59c, 0x066,	0x59d, 0x090,	0x59e, 0x001,	0x584, 0x000,	0x585, 0x000,	0x586, 0x003,	0x588, 0x0ff,	0x589, 0x00f,	0x58a, 0x000,	0x58b, 0x000,	0x58c, 0x010,	0x58d, 0x032,	0x58e, 0x054,	0x58f, 0x023,	0x590, 0x000,	0x595, 0x000,	0x596, 0x000,	0x597, 0x000,	0x464, 0x000,	0x46c, 0xbbbb10,	0x470, 0x101010,	0x478, 0x000,	0x474, 0x018,	0x454, 0x042135,	0x598, 0x0e7,	0x599, 0x07d,	0x59a, 0x018,	0x59c, 0x066,	0x59d, 0x090,	0x59e, 0x001,	0x584, 0x000,	0x585, 0x000,	0x586, 0x003,	0x588, 0x0ff,	0x589, 0x00f,	0x58a, 0x000,	0x58b, 0x000,	0x58c, 0x010,	0x58d, 0x032,	0x58e, 0x054,	0x58f, 0x023,	0x590, 0x000,	0x595, 0x000,	0x596, 0x000,	0x597, 0x000,	0x464, 0x000,	0x46c, 0xbbbb10,	0x470, 0x101010,	0x478, 0x000,	0x474, 0x018,	0x454, 0x042135,	0x598, 0x0e7,	0x599, 0x07d,	0x59a, 0x018,	0x59c, 0x066,	0x59d, 0x090,	0x59e, 0x001,	0x584, 0x000,	0x585, 0x000,	0x586, 0x003,	0x588, 0x0ff,	0x589, 0x00f,	0x58a, 0x000,	0x58b, 0x000,	0x58c, 0x010,	0x58d, 0x032,	0x58e, 0x054,	0x58f, 0x023,	0x590, 0x000,	0x595, 0x000,	0x596, 0x000,	0x597, 0x000,	0x464, 0x000,	0x46c, 0xbbbb10,	0x470, 0x101010,	0x478, 0x000,	0x474, 0x018,	0x454, 0x042135,	0x193, 0x000,	0x300, 0x000,	0x301, 0x006,	0x302, 0x000,

⌨️ 快捷键说明

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