V4L/DVB (5314): Added support for tda827x tuners with preamlifiers
This patch contains - new tuning code for the tda827xa silicon tuner. - controls the preamplifier of some boards with this tuner. - support for the Philips Tiger S hybrid DVB-T reference design. - reworked the saa7134-dvb modulue to get rid of most of the small board specific functions. Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
de956c1e0f
commit
58ef4f924c
|
@ -107,3 +107,4 @@
|
|||
106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344]
|
||||
107 -> Encore ENLTV-FM [1131:230f]
|
||||
108 -> Terratec Cinergy HT PCI [153b:1175]
|
||||
109 -> Philips Tiger - S Reference design
|
||||
|
|
|
@ -2543,10 +2543,10 @@ struct saa7134_board saa7134_boards[] = {
|
|||
.name = "Philips Tiger reference design",
|
||||
.audio_clock = 0x00187de7,
|
||||
.tuner_type = TUNER_PHILIPS_TDA8290,
|
||||
.tuner_config = 0,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.tuner_config = 0,
|
||||
.mpeg = SAA7134_MPEG_DVB,
|
||||
.gpiomask = 0x0200000,
|
||||
.inputs = {{
|
||||
|
@ -2625,7 +2625,7 @@ struct saa7134_board saa7134_boards[] = {
|
|||
}},
|
||||
.radio = {
|
||||
.name = name_radio,
|
||||
.amux = LINE1,
|
||||
.amux = TV,
|
||||
.gpio = 0x0200000,
|
||||
},
|
||||
},
|
||||
|
@ -3044,6 +3044,7 @@ struct saa7134_board saa7134_boards[] = {
|
|||
.radio_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.tuner_config = 1,
|
||||
.mpeg = SAA7134_MPEG_DVB,
|
||||
.gpiomask = 0x000200000,
|
||||
.inputs = {{
|
||||
|
@ -3290,6 +3291,36 @@ struct saa7134_board saa7134_boards[] = {
|
|||
.amux = LINE1,
|
||||
}},
|
||||
},
|
||||
[SAA7134_BOARD_PHILIPS_TIGER_S] = {
|
||||
.name = "Philips Tiger - S Reference design",
|
||||
.audio_clock = 0x00187de7,
|
||||
.tuner_type = TUNER_PHILIPS_TDA8290,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.tuner_config = 2,
|
||||
.mpeg = SAA7134_MPEG_DVB,
|
||||
.gpiomask = 0x0200000,
|
||||
.inputs = {{
|
||||
.name = name_tv,
|
||||
.vmux = 1,
|
||||
.amux = TV,
|
||||
.tv = 1,
|
||||
},{
|
||||
.name = name_comp1,
|
||||
.vmux = 3,
|
||||
.amux = LINE1,
|
||||
},{
|
||||
.name = name_svideo,
|
||||
.vmux = 8,
|
||||
.amux = LINE1,
|
||||
}},
|
||||
.radio = {
|
||||
.name = name_radio,
|
||||
.amux = TV,
|
||||
.gpio = 0x0200000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
|
||||
|
@ -4104,8 +4135,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
|
|||
break;
|
||||
case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
|
||||
case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
|
||||
saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
|
||||
saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00);
|
||||
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08000000, 0x08000000);
|
||||
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000);
|
||||
break;
|
||||
case SAA7134_BOARD_AVERMEDIA_CARDBUS:
|
||||
/* power-up tuner chip */
|
||||
|
@ -4168,6 +4199,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
|
|||
tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
|
||||
tun_setup.type = dev->tuner_type;
|
||||
tun_setup.addr = ADDR_UNSET;
|
||||
tun_setup.config = 0;
|
||||
tun_setup.gpio_func = NULL;
|
||||
|
||||
saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
|
||||
}
|
||||
|
@ -4235,6 +4268,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
|
|||
tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
|
||||
tun_setup.type = dev->tuner_type;
|
||||
tun_setup.addr = ADDR_UNSET;
|
||||
tun_setup.config = 0;
|
||||
tun_setup.gpio_func = NULL;
|
||||
|
||||
saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
|
||||
}
|
||||
|
@ -4254,11 +4289,36 @@ int saa7134_board_init2(struct saa7134_dev *dev)
|
|||
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
|
||||
tun_setup.type = dev->tuner_type;
|
||||
tun_setup.addr = dev->tuner_addr;
|
||||
tun_setup.config = 0;
|
||||
tun_setup.gpio_func = NULL;
|
||||
|
||||
saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
|
||||
}
|
||||
break;
|
||||
case SAA7134_BOARD_PHILIPS_TIGER:
|
||||
case SAA7134_BOARD_PHILIPS_TIGER_S:
|
||||
{
|
||||
u8 data[] = { 0x3c, 0x33, 0x60};
|
||||
struct tuner_setup tun_setup;
|
||||
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
|
||||
if(dev->autodetected && (dev->eedata[0x49] == 0x50)) {
|
||||
dev->board = SAA7134_BOARD_PHILIPS_TIGER_S;
|
||||
printk(KERN_INFO "%s: Reconfigured board as %s\n",
|
||||
dev->name, saa7134_boards[dev->board].name);
|
||||
}
|
||||
if(dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
|
||||
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
|
||||
tun_setup.type = TUNER_PHILIPS_TDA8290;
|
||||
tun_setup.addr = 0x4b;
|
||||
tun_setup.config = 2;
|
||||
tun_setup.gpio_func = (tuner_gpio_func_t) saa7134_set_gpio;
|
||||
|
||||
saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
|
||||
data[2] = 0x68;
|
||||
}
|
||||
i2c_transfer(&dev->i2c_adap, &msg, 1);
|
||||
}
|
||||
break;
|
||||
case SAA7134_BOARD_PINNACLE_PCTV_310i:
|
||||
case SAA7134_BOARD_TEVION_DVBT_220RF:
|
||||
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
|
||||
|
@ -4268,7 +4328,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
|
|||
* and configure firmware eeprom address
|
||||
*/
|
||||
{
|
||||
u8 data[] = { 0x3c, 0x33, 0x68};
|
||||
u8 data[] = { 0x3c, 0x33, 0x60};
|
||||
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
|
||||
i2c_transfer(&dev->i2c_adap, &msg, 1);
|
||||
}
|
||||
|
@ -4282,18 +4342,18 @@ int saa7134_board_init2(struct saa7134_dev *dev)
|
|||
break;
|
||||
case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
|
||||
case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
|
||||
/* make the tda10046 find its eeprom */
|
||||
/* initialize analog mode */
|
||||
{
|
||||
u8 data[] = { 0x3c, 0x33, 0x62};
|
||||
u8 data[] = { 0x3c, 0x33, 0x6a};
|
||||
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
|
||||
i2c_transfer(&dev->i2c_adap, &msg, 1);
|
||||
}
|
||||
break;
|
||||
case SAA7134_BOARD_CINERGY_HT_PCMCIA:
|
||||
case SAA7134_BOARD_CINERGY_HT_PCI:
|
||||
/* make the tda10046 find its eeprom */
|
||||
/* initialize analog mode */
|
||||
{
|
||||
u8 data[] = { 0x3c, 0x33, 0x60};
|
||||
u8 data[] = { 0x3c, 0x33, 0x68};
|
||||
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
|
||||
i2c_transfer(&dev->i2c_adap, &msg, 1);
|
||||
}
|
||||
|
|
|
@ -1205,6 +1205,7 @@ module_exit(saa7134_fini);
|
|||
|
||||
/* ----------------------------------------------------------- */
|
||||
|
||||
EXPORT_SYMBOL(saa7134_set_gpio);
|
||||
EXPORT_SYMBOL(saa7134_i2c_call_clients);
|
||||
EXPORT_SYMBOL(saa7134_devlist);
|
||||
EXPORT_SYMBOL(saa7134_boards);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -603,7 +603,14 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
|
|||
saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40);
|
||||
saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
|
||||
|
||||
saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
|
||||
/* only tell the tuner if this is a tv input */
|
||||
if (card_in(dev,dev->ctl_input).tv) {
|
||||
if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
|
||||
&& ((card(dev).tuner_config == 1)
|
||||
|| (card(dev).tuner_config == 2)))
|
||||
saa7134_set_gpio(dev, 22, 5);
|
||||
saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
|
||||
}
|
||||
}
|
||||
|
||||
static void video_mux(struct saa7134_dev *dev, int input)
|
||||
|
|
|
@ -231,6 +231,7 @@ struct saa7134_format {
|
|||
#define SAA7134_BOARD_ENCORE_ENLTV 106
|
||||
#define SAA7134_BOARD_ENCORE_ENLTV_FM 107
|
||||
#define SAA7134_BOARD_CINERGY_HT_PCI 108
|
||||
#define SAA7134_BOARD_PHILIPS_TIGER_S 109
|
||||
|
||||
#define SAA7134_MAXBOARDS 8
|
||||
#define SAA7134_INPUT_MAX 8
|
||||
|
|
|
@ -192,14 +192,52 @@ static struct tda827xa_data tda827xa_analog[] = {
|
|||
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
|
||||
};
|
||||
|
||||
static void tda827xa_lna_gain(struct i2c_client *c, int high)
|
||||
{
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
unsigned char buf[] = {0x22, 0x01};
|
||||
int arg;
|
||||
struct i2c_msg msg = {.addr = c->addr, .flags = 0, .buf = buf, .len = sizeof(buf)};
|
||||
if (t->config) {
|
||||
if (high)
|
||||
tuner_dbg("setting LNA to high gain\n");
|
||||
else
|
||||
tuner_dbg("setting LNA to low gain\n");
|
||||
}
|
||||
switch (t->config) {
|
||||
case 0: /* no LNA */
|
||||
break;
|
||||
case 1: /* switch is GPIO 0 of tda8290 */
|
||||
case 2:
|
||||
/* turn Vsync on */
|
||||
if (t->std & V4L2_STD_MN)
|
||||
arg = 5;
|
||||
else
|
||||
arg = 4;
|
||||
if (t->gpio_func)
|
||||
t->gpio_func(c->adapter->algo_data, 22, 5);
|
||||
buf[1] = high ? 0 : 1;
|
||||
if (t->config == 2)
|
||||
buf[1] = high ? 1 : 0;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
break;
|
||||
case 3: /* switch with GPIO of saa713x */
|
||||
if (t->gpio_func)
|
||||
t->gpio_func(c->adapter->algo_data, 22, high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
|
||||
{
|
||||
unsigned char tuner_reg[14];
|
||||
unsigned char reg2[2];
|
||||
unsigned char tuner_reg[11];
|
||||
u32 N;
|
||||
int i;
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
|
||||
struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0, .buf = tuner_reg};
|
||||
|
||||
tda827xa_lna_gain( c, 1);
|
||||
msleep(10);
|
||||
|
||||
if (t->mode == V4L2_TUNER_RADIO)
|
||||
freq = freq / 1000;
|
||||
|
@ -222,48 +260,58 @@ static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
|
|||
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[7] = 0x1c;
|
||||
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;
|
||||
tuner_reg[10] = 0x00;
|
||||
msg.len = 11;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
|
||||
msg.buf= reg2;
|
||||
tuner_reg[0] = 0x90;
|
||||
tuner_reg[1] = 0xff;
|
||||
tuner_reg[2] = 0xe0;
|
||||
tuner_reg[3] = 0;
|
||||
tuner_reg[4] = 0x99 + (t->tda827x_lpsel << 1);
|
||||
msg.len = 5;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
|
||||
tuner_reg[0] = 0xa0;
|
||||
tuner_reg[1] = 0xc0;
|
||||
msg.len = 2;
|
||||
reg2[0] = 0x60;
|
||||
reg2[1] = 0x3c;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
|
||||
reg2[0] = 0xa0;
|
||||
reg2[1] = 0xc0;
|
||||
tuner_reg[0] = 0x30;
|
||||
tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
|
||||
msleep(2);
|
||||
reg2[0] = 0x30;
|
||||
reg2[1] = 0x10 + tda827xa_analog[i].scr;
|
||||
msg.flags = I2C_M_RD;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
msg.flags = 0;
|
||||
tuner_reg[1] >>= 4;
|
||||
tuner_dbg("AGC2 gain is: %d\n", tuner_reg[1]);
|
||||
if (tuner_reg[1] < 1)
|
||||
tda827xa_lna_gain( c, 0);
|
||||
|
||||
msleep(100);
|
||||
tuner_reg[0] = 0x60;
|
||||
tuner_reg[1] = 0x3c;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
|
||||
msleep(550);
|
||||
reg2[0] = 0x50;
|
||||
reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
|
||||
msleep(163);
|
||||
tuner_reg[0] = 0x50;
|
||||
tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
|
||||
reg2[0] = 0x80;
|
||||
reg2[1] = 0x28;
|
||||
tuner_reg[0] = 0x80;
|
||||
tuner_reg[1] = 0x28;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
|
||||
reg2[0] = 0xb0;
|
||||
reg2[1] = 0x01;
|
||||
tuner_reg[0] = 0xb0;
|
||||
tuner_reg[1] = 0x01;
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
|
||||
reg2[0] = 0xc0;
|
||||
reg2[1] = 0x19 + (t->tda827x_lpsel << 1);
|
||||
tuner_reg[0] = 0xc0;
|
||||
tuner_reg[1] = 0x19 + (t->tda827x_lpsel << 1);
|
||||
i2c_transfer(c->adapter, &msg, 1);
|
||||
}
|
||||
|
||||
|
@ -319,7 +367,9 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
|
|||
unsigned char addr_pll_stat = 0x1b;
|
||||
unsigned char adc_sat, agc_stat,
|
||||
pll_stat;
|
||||
int i;
|
||||
|
||||
tuner_dbg("tda827xa config is 0x%02x\n", t->config);
|
||||
i2c_master_send(c, easy_mode, 2);
|
||||
i2c_master_send(c, agc_out_on, 2);
|
||||
i2c_master_send(c, soft_reset, 2);
|
||||
|
@ -340,17 +390,22 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
|
|||
tda827xa_tune(c, ifc, freq);
|
||||
else
|
||||
tda827x_tune(c, ifc, freq);
|
||||
for (i = 0; i < 3; i++) {
|
||||
i2c_master_send(c, &addr_pll_stat, 1);
|
||||
i2c_master_recv(c, &pll_stat, 1);
|
||||
if (pll_stat & 0x80) {
|
||||
i2c_master_send(c, &addr_adc_sat, 1);
|
||||
i2c_master_recv(c, &adc_sat, 1);
|
||||
i2c_master_send(c, &addr_agc_stat, 1);
|
||||
i2c_master_recv(c, &agc_stat, 1);
|
||||
tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
|
||||
break;
|
||||
} else {
|
||||
tuner_dbg("tda8290 not locked, no signal?\n");
|
||||
msleep(100);
|
||||
}
|
||||
}
|
||||
/* adjust headroom resp. gain */
|
||||
i2c_master_send(c, &addr_adc_sat, 1);
|
||||
i2c_master_recv(c, &adc_sat, 1);
|
||||
i2c_master_send(c, &addr_agc_stat, 1);
|
||||
i2c_master_recv(c, &agc_stat, 1);
|
||||
i2c_master_send(c, &addr_pll_stat, 1);
|
||||
i2c_master_recv(c, &pll_stat, 1);
|
||||
if (pll_stat & 0x80)
|
||||
tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
|
||||
else
|
||||
tuner_dbg("tda8290 not locked, no signal?\n");
|
||||
if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
|
||||
tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
|
||||
agc_stat, adc_sat, pll_stat & 0x80);
|
||||
|
@ -487,11 +542,16 @@ static void standby(struct i2c_client *c)
|
|||
|
||||
static void tda8290_init_if(struct i2c_client *c)
|
||||
{
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
unsigned char set_VS[] = { 0x30, 0x6F };
|
||||
unsigned char set_GP00_CF[] = { 0x20, 0x01 };
|
||||
unsigned char set_GP01_CF[] = { 0x20, 0x0B };
|
||||
|
||||
if ((t->config == 1) || (t->config == 2))
|
||||
i2c_master_send(c, set_GP00_CF, 2);
|
||||
else
|
||||
i2c_master_send(c, set_GP01_CF, 2);
|
||||
i2c_master_send(c, set_VS, 2);
|
||||
i2c_master_send(c, set_GP01_CF, 2);
|
||||
}
|
||||
|
||||
static void tda8290_init_tuner(struct i2c_client *c)
|
||||
|
|
Loading…
Reference in New Issue