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

📄 tda8290.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   i2c tv tuner chip device driver   controls the philips tda8290+75 tuner chip combo.   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/i2c.h>#include <linux/videodev.h>#include <linux/delay.h>#include <media/tuner.h>/* ---------------------------------------------------------------------- */struct tda827x_data {	u32 lomax;	u8  spd;	u8  bs;	u8  bp;	u8  cp;	u8  gc3;	u8 div1p5;};     /* Note lomax entry is lo / 62500 */static struct tda827x_data tda827x_analog[] = {	{ .lomax =   992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /*  62 MHz */	{ .lomax =  1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /*  66 MHz */	{ .lomax =  1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /*  76 MHz */	{ .lomax =  1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /*  84 MHz */	{ .lomax =  1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /*  93 MHz */	{ .lomax =  1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /*  98 MHz */	{ .lomax =  1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */	{ .lomax =  1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */	{ .lomax =  2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */	{ .lomax =  2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */	{ .lomax =  2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */	{ .lomax =  2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */	{ .lomax =  2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */	{ .lomax =  3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */	{ .lomax =  3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */	{ .lomax =  4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */	{ .lomax =  4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */	{ .lomax =  5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */	{ .lomax =  5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */	{ .lomax =  7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */	{ .lomax =  7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */	{ .lomax =  8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */	{ .lomax =  8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */	{ .lomax =  9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */	{ .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */	{ .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */	{ .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */	{ .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */	{ .lomax =     0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}  /* End      */};static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq){	unsigned char tuner_reg[8];	unsigned char reg2[2];	u32 N;	int i;	struct tuner *t = i2c_get_clientdata(c);	struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};	if (t->mode == V4L2_TUNER_RADIO)		freq = freq / 1000;	N = freq + ifc;	i = 0;	while (tda827x_analog[i].lomax < N) {		if(tda827x_analog[i + 1].lomax == 0)			break;		i++;	}	N = N << tda827x_analog[i].spd;	tuner_reg[0] = 0;	tuner_reg[1] = (unsigned char)(N>>8);	tuner_reg[2] = (unsigned char) N;	tuner_reg[3] = 0x40;	tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5);	tuner_reg[5] = (tda827x_analog[i].spd   << 6) + (tda827x_analog[i].div1p5 <<5) +		       (tda827x_analog[i].bs     <<3) +  tda827x_analog[i].bp;	tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4);	tuner_reg[7] = 0x8f;	msg.buf = tuner_reg;	msg.len = 8;	i2c_transfer(c->adapter, &msg, 1);	msg.buf= reg2;	msg.len = 2;	reg2[0] = 0x80;	reg2[1] = 0;	i2c_transfer(c->adapter, &msg, 1);	reg2[0] = 0x60;	reg2[1] = 0xbf;	i2c_transfer(c->adapter, &msg, 1);	reg2[0] = 0x30;	reg2[1] = tuner_reg[4] + 0x80;	i2c_transfer(c->adapter, &msg, 1);	msleep(1);	reg2[0] = 0x30;	reg2[1] = tuner_reg[4] + 4;	i2c_transfer(c->adapter, &msg, 1);	msleep(1);	reg2[0] = 0x30;	reg2[1] = tuner_reg[4];	i2c_transfer(c->adapter, &msg, 1);	msleep(550);	reg2[0] = 0x30;	reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ;	i2c_transfer(c->adapter, &msg, 1);	reg2[0] = 0x60;	reg2[1] = 0x3f;	i2c_transfer(c->adapter, &msg, 1);	reg2[0] = 0x80;	reg2[1] = 0x08;   // Vsync en	i2c_transfer(c->adapter, &msg, 1);}static void tda827x_agcf(struct i2c_client *c){	struct tuner *t = i2c_get_clientdata(c);	unsigned char data[] = {0x80, 0x0c};	struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,			      .flags = 0, .len = 2};	i2c_transfer(c->adapter, &msg, 1);}/* ---------------------------------------------------------------------- */struct tda827xa_data {	u32 lomax;	u8  svco;	u8  spd;	u8  scr;	u8  sbs;	u8  gc3;};static struct tda827xa_data tda827xa_analog[] = {	{ .lomax =   910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},  /*  56.875 MHz */	{ .lomax =  1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},  /*  67.25 MHz */	{ .lomax =  1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},  /*  81.25 MHz */	{ .lomax =  1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},  /*  97.5  MHz */	{ .lomax =  1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},  /* 113.75 MHz */	{ .lomax =  2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},  /* 134.5 MHz */	{ .lomax =  2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},  /* 154   MHz */	{ .lomax =  2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},  /* 162.5 MHz */	{ .lomax =  2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},  /* 183   MHz */	{ .lomax =  3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},  /* 195   MHz */	{ .lomax =  3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},  /* 227.5 MHz */	{ .lomax =  4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},  /* 269   MHz */	{ .lomax =  5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},  /* 325   MHz */	{ .lomax =  6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},  /* 390   MHz */	{ .lomax =  7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},  /* 455   MHz */	{ .lomax =  8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},  /* 520   MHz */	{ .lomax =  8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},  /* 538   MHz */	{ .lomax =  8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},  /* 554   MHz */	{ .lomax =  9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},  /* 620   MHz */	{ .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},  /* 650   MHz */	{ .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},  /* 700   MHz */	{ .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},  /* 780   MHz */	{ .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},  /* 820   MHz */	{ .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},  /* 870   MHz */	{ .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},  /* 911   MHz */	{ .lomax =     0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}   /* End */};static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq){	unsigned char tuner_reg[14];	unsigned char reg2[2];	u32 N;	int i;	struct tuner *t = i2c_get_clientdata(c);	struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};	if (t->mode == V4L2_TUNER_RADIO)		freq = freq / 1000;	N = freq + ifc;	i = 0;	while (tda827xa_analog[i].lomax < N) {		if(tda827xa_analog[i + 1].lomax == 0)			break;		i++;	}	N = N << tda827xa_analog[i].spd;	tuner_reg[0] = 0;	tuner_reg[1] = (unsigned char)(N>>8);	tuner_reg[2] = (unsigned char) N;	tuner_reg[3] = 0;	tuner_reg[4] = 0x16;	tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) +			tda827xa_analog[i].sbs;	tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);	tuner_reg[7] = 0x0c;	tuner_reg[8] = 4;	tuner_reg[9] = 0x20;	tuner_reg[10] = 0xff;	tuner_reg[11] = 0xe0;	tuner_reg[12] = 0;	tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1);	msg.buf = tuner_reg;	msg.len = 14;	i2c_transfer(c->adapter, &msg, 1);	msg.buf= reg2;	msg.len = 2;	reg2[0] = 0x60;	reg2[1] = 0x3c;	i2c_transfer(c->adapter, &msg, 1);	reg2[0] = 0xa0;	reg2[1] = 0xc0;	i2c_transfer(c->adapter, &msg, 1);	msleep(2);	reg2[0] = 0x30;	reg2[1] = 0x10 + tda827xa_analog[i].scr;	i2c_transfer(c->adapter, &msg, 1);	msleep(550);	reg2[0] = 0x50;	reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);	i2c_transfer(c->adapter, &msg, 1);	reg2[0] = 0x80;	reg2[1] = 0x28;	i2c_transfer(c->adapter, &msg, 1);	reg2[0] = 0xb0;	reg2[1] = 0x01;	i2c_transfer(c->adapter, &msg, 1);	reg2[0] = 0xc0;	reg2[1] = 0x19 + (t->tda827x_lpsel << 1);	i2c_transfer(c->adapter, &msg, 1);}static void tda827xa_agcf(struct i2c_client *c){	struct tuner *t = i2c_get_clientdata(c);	unsigned char data[] = {0x80, 0x2c};	struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,			      .flags = 0, .len = 2};	i2c_transfer(c->adapter, &msg, 1);}/*---------------------------------------------------------------------*/static void tda8290_i2c_bridge(struct i2c_client *c, int close){	unsigned char  enable[2] = { 0x21, 0xC0 };	unsigned char disable[2] = { 0x21, 0x80 };	unsigned char *msg;	if(close) {		msg = enable;		i2c_master_send(c, msg, 2);		/* let the bridge stabilize */		msleep(20);	} else {		msg = disable;		i2c_master_send(c, msg, 2);	}}/*---------------------------------------------------------------------*/static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq){	struct tuner *t = i2c_get_clientdata(c);	unsigned char soft_reset[]  = { 0x00, 0x00 };	unsigned char easy_mode[]   = { 0x01, t->tda8290_easy_mode };	unsigned char expert_mode[] = { 0x01, 0x80 };	unsigned char gainset_off[] = { 0x28, 0x14 };	unsigned char if_agc_spd[]  = { 0x0f, 0x88 };	unsigned char adc_head_6[]  = { 0x05, 0x04 };	unsigned char adc_head_9[]  = { 0x05, 0x02 };	unsigned char adc_head_12[] = { 0x05, 0x01 };

⌨️ 快捷键说明

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