in pci/saa7134/saa7134-cards.c [7754:8127]
int saa7134_board_init2(struct saa7134_dev *dev)
{
unsigned char buf;
int board;
/* Put here the code that enables the chips that are needed
for analog mode and doesn't depend on the tuner attachment.
It is also a good idea to get tuner type from eeprom, etc before
initializing tuner, since we can avoid loading tuner driver
on devices that has TUNER_ABSENT
*/
switch (dev->board) {
case SAA7134_BOARD_BMK_MPEX_NOTUNER:
case SAA7134_BOARD_BMK_MPEX_TUNER:
/* Checks if the device has a tuner at 0x60 addr
If the device doesn't have a tuner, TUNER_ABSENT
will be used at tuner_type, avoiding loading tuner
without needing it
*/
dev->i2c_client.addr = 0x60;
board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
? SAA7134_BOARD_BMK_MPEX_NOTUNER
: SAA7134_BOARD_BMK_MPEX_TUNER;
if (board == dev->board)
break;
dev->board = board;
pr_warn("%s: board type fixup: %s\n", dev->name,
saa7134_boards[dev->board].name);
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
break;
case SAA7134_BOARD_MD7134:
{
u8 subaddr;
u8 data[3], data1[] = { 0x09, 0x9f, 0x86, 0x11};
int ret, tuner_t;
struct i2c_msg msg[] = {{.addr = 0x50, .flags = 0, .buf = &subaddr, .len = 1},
{.addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = 3}},
msg1 = {.addr = 0x61, .flags = 0, .buf = data1, .len = sizeof(data1)};
subaddr= 0x14;
tuner_t = 0;
/* Retrieve device data from eeprom, checking for the
proper tuner_type.
*/
ret = i2c_transfer(&dev->i2c_adap, msg, 2);
if (ret != 2) {
pr_err("EEPROM read failure\n");
} else if ((data[0] != 0) && (data[0] != 0xff)) {
/* old config structure */
subaddr = data[0] + 2;
msg[1].len = 2;
i2c_transfer(&dev->i2c_adap, msg, 2);
tuner_t = (data[0] << 8) + data[1];
switch (tuner_t){
case 0x0103:
dev->tuner_type = TUNER_PHILIPS_PAL;
break;
case 0x010C:
dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
break;
default:
pr_err("%s Can't determine tuner type %x from EEPROM\n",
dev->name, tuner_t);
}
} else if ((data[1] != 0) && (data[1] != 0xff)) {
/* new config structure */
subaddr = data[1] + 1;
msg[1].len = 1;
i2c_transfer(&dev->i2c_adap, msg, 2);
subaddr = data[0] + 1;
msg[1].len = 2;
i2c_transfer(&dev->i2c_adap, msg, 2);
tuner_t = (data[1] << 8) + data[0];
switch (tuner_t) {
case 0x0005:
dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
break;
case 0x001d:
dev->tuner_type = TUNER_PHILIPS_FMD1216ME_MK3;
pr_info("%s Board has DVB-T\n",
dev->name);
break;
default:
pr_err("%s Can't determine tuner type %x from EEPROM\n",
dev->name, tuner_t);
}
} else {
pr_err("%s unexpected config structure\n", dev->name);
}
pr_info("%s Tuner type is %d\n", dev->name, dev->tuner_type);
/* The tuner TUNER_PHILIPS_FMD1216ME_MK3 after hardware */
/* start has disabled IF and enabled DVB-T. When saa7134 */
/* scan I2C devices it will not detect IF tda9887 and can`t*/
/* watch TV without software reboot. To solve this problem */
/* switch the tuner to analog TV mode manually. */
if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) {
if (i2c_transfer(&dev->i2c_adap, &msg1, 1) != 1)
printk(KERN_WARNING "%s: Unable to enable IF of the tuner.\n", dev->name);
}
break;
}
case SAA7134_BOARD_PHILIPS_EUROPA:
if (dev->autodetected && (dev->eedata[0x41] == 0x1c)) {
/* Reconfigure board as Snake reference design */
dev->board = SAA7134_BOARD_PHILIPS_SNAKE;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
pr_info("%s: Reconfigured board as %s\n",
dev->name, saa7134_boards[dev->board].name);
break;
}
fallthrough;
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
case SAA7134_BOARD_TECHNOTREND_BUDGET_T3000:
{
/* The Philips EUROPA based hybrid boards have the tuner
connected through the channel decoder. We have to make it
transparent to find it
*/
u8 data[] = { 0x07, 0x02};
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
case SAA7134_BOARD_PHILIPS_TIGER:
case SAA7134_BOARD_PHILIPS_TIGER_S:
{
u8 data[] = { 0x3c, 0x33, 0x60};
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;
pr_info("%s: Reconfigured board as %s\n",
dev->name, saa7134_boards[dev->board].name);
}
if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
dev->tuner_type = TUNER_PHILIPS_TDA8290;
data[2] = 0x68;
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
case SAA7134_BOARD_ASUSTeK_TVFM7135:
/* The card below is detected as card=53, but is different */
if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
pr_info("%s: P7131 analog only, using entry of %s\n",
dev->name, saa7134_boards[dev->board].name);
/*
* IR init has already happened for other cards, so
* we have to catch up.
*/
dev->has_remote = SAA7134_REMOTE_GPIO;
saa7134_input_init1(dev);
}
break;
case SAA7134_BOARD_HAUPPAUGE_HVR1150:
case SAA7134_BOARD_HAUPPAUGE_HVR1120:
hauppauge_eeprom(dev, dev->eedata+0x80);
break;
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
hauppauge_eeprom(dev, dev->eedata+0x80);
fallthrough;
case SAA7134_BOARD_PINNACLE_PCTV_310i:
case SAA7134_BOARD_KWORLD_DVBT_210:
case SAA7134_BOARD_TEVION_DVBT_220RF:
case SAA7134_BOARD_ASUSTeK_TIGER:
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
case SAA7134_BOARD_MEDION_MD8800_QUADRO:
case SAA7134_BOARD_AVERMEDIA_SUPER_007:
case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
case SAA7134_BOARD_CREATIX_CTX953:
{
/* this is a hybrid board, initialize to analog mode
* and configure firmware eeprom address
*/
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);
break;
}
case SAA7134_BOARD_ASUSTeK_TIGER_3IN1:
{
u8 data[] = { 0x3c, 0x33, 0x60};
struct i2c_msg msg = {.addr = 0x0b, .flags = 0, .buf = data,
.len = sizeof(data)};
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
case SAA7134_BOARD_ASUSTeK_PS3_100:
{
u8 data[] = { 0x3c, 0x33, 0x60};
struct i2c_msg msg = {.addr = 0x0b, .flags = 0, .buf = data,
.len = sizeof(data)};
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
case SAA7134_BOARD_FLYDVB_TRIO:
{
u8 temp = 0;
int rc;
u8 data[] = { 0x3c, 0x33, 0x62};
struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)};
i2c_transfer(&dev->i2c_adap, &msg, 1);
/*
* send weak up message to pic16C505 chip
* @ LifeView FlyDVB Trio
*/
msg.buf = &temp;
msg.addr = 0x0b;
msg.len = 1;
if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) {
pr_warn("%s: send wake up byte to pic16C505(IR chip) failed\n",
dev->name);
} else {
msg.flags = I2C_M_RD;
rc = i2c_transfer(&dev->i2c_adap, &msg, 1);
pr_info("%s: probe IR chip @ i2c 0x%02x: %s\n",
dev->name, msg.addr,
(1 == rc) ? "yes" : "no");
if (rc == 1)
dev->has_remote = SAA7134_REMOTE_I2C;
}
break;
}
case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
{
/* initialize analog mode */
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:
{
/* initialize analog mode */
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);
break;
}
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
/* The T200 and the T200A share the same pci id. Consequently,
* we are going to query eeprom to try to find out which one we
* are actually looking at. */
/* Don't do this if the board was specifically selected with an
* insmod option or if we have the default configuration T200*/
if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
break;
if (dev->eedata[0x41] == 0x02) {
/* Reconfigure board as T200A */
dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
pr_info("%s: Reconfigured board as %s\n",
dev->name, saa7134_boards[dev->board].name);
} else {
pr_warn("%s: Unexpected tuner type info: %x in eeprom\n",
dev->name, dev->eedata[0x41]);
break;
}
break;
case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
case SAA7134_BOARD_KWORLD_ATSC110:
{
struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
int i;
static u8 buffer[][2] = {
{ 0x10, 0x12 },
{ 0x13, 0x04 },
{ 0x16, 0x00 },
{ 0x14, 0x04 },
{ 0x17, 0x00 },
};
for (i = 0; i < ARRAY_SIZE(buffer); i++) {
msg.buf = &buffer[i][0];
msg.len = ARRAY_SIZE(buffer[0]);
if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
pr_warn("%s: Unable to enable tuner(%i).\n",
dev->name, i);
}
break;
}
case SAA7134_BOARD_BEHOLD_H6:
{
u8 data[] = { 0x09, 0x9f, 0x86, 0x11};
struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = data,
.len = sizeof(data)};
/* The tuner TUNER_PHILIPS_FMD1216MEX_MK3 after hardware */
/* start has disabled IF and enabled DVB-T. When saa7134 */
/* scan I2C devices it not detect IF tda9887 and can`t */
/* watch TV without software reboot. For solve this problem */
/* switch the tuner to analog TV mode manually. */
if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
pr_warn("%s: Unable to enable IF of the tuner.\n",
dev->name);
break;
}
case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);
saa7134_set_gpio(dev, 27, 0);
break;
} /* switch() */
/* initialize tuner (don't do this when resuming) */
if (!dev->insuspend && TUNER_ABSENT != dev->tuner_type) {
int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
/* Note: radio tuner address is always filled in,
so we do not need to probe for a radio tuner device. */
if (dev->radio_type != UNSET)
v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_adap, "tuner",
dev->radio_addr, NULL);
if (has_demod)
v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
if (dev->tuner_addr == ADDR_UNSET) {
enum v4l2_i2c_tuner_type type =
has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(type));
} else {
v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_adap, "tuner",
dev->tuner_addr, NULL);
}
}
saa7134_tuner_setup(dev);
switch (dev->board) {
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
{
struct v4l2_priv_tun_config tea5767_cfg;
struct tea5767_ctrl ctl;
dev->i2c_client.addr = 0xC0;
/* set TEA5767(analog FM) defines */
memset(&ctl, 0, sizeof(ctl));
ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
tea5767_cfg.tuner = TUNER_TEA5767;
tea5767_cfg.priv = &ctl;
saa_call_all(dev, tuner, s_config, &tea5767_cfg);
break;
}
} /* switch() */
return 0;
}