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 + -
显示快捷键?