Commit b9348353 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

V4L/DVB (10507): saa7134: Fix analog mode on devices that need to open an i2c gate

Some saa7134 devices require to open an i2c gate before tuning. This
patch fix the initialization for those devices.

The nxt200x_gate_ctrl() logic were returned back to the old place, since
we don't know how to close the gate. A future pacth could revert that
change and provide the proper close gate control, to avoid keeping it
open forever.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 18b1ae7d
...@@ -5896,32 +5896,6 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) ...@@ -5896,32 +5896,6 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
static void nxt200x_gate_ctrl(struct saa7134_dev *dev, int open)
{
/* enable tuner */
int i;
static const u8 buffer [][2] = {
{ 0x10, 0x12 },
{ 0x13, 0x04 },
{ 0x16, 0x00 },
{ 0x14, 0x04 },
{ 0x17, 0x00 },
};
dev->i2c_client.addr = 0x0a;
/* FIXME: don't know how to close the i2c gate on NXT200x */
if (!open)
return;
for (i = 0; i < ARRAY_SIZE(buffer); i++)
if (2 != i2c_master_send(&dev->i2c_client,
&buffer[i][0], ARRAY_SIZE(buffer[0])))
printk(KERN_WARNING
"%s: Unable to enable tuner(%i).\n",
dev->name, i);
}
int saa7134_board_init1(struct saa7134_dev *dev) int saa7134_board_init1(struct saa7134_dev *dev)
{ {
/* Always print gpio, often manufacturers encode tuner type and other info. */ /* Always print gpio, often manufacturers encode tuner type and other info. */
...@@ -6115,10 +6089,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) ...@@ -6115,10 +6089,6 @@ int saa7134_board_init1(struct saa7134_dev *dev)
"are supported for now.\n", "are supported for now.\n",
dev->name, card(dev).name, dev->name); dev->name, card(dev).name, dev->name);
break; break;
case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
case SAA7134_BOARD_KWORLD_ATSC110:
dev->gate_ctrl = nxt200x_gate_ctrl;
break;
} }
return 0; return 0;
} }
...@@ -6197,33 +6167,20 @@ int saa7134_board_init2(struct saa7134_dev *dev) ...@@ -6197,33 +6167,20 @@ int saa7134_board_init2(struct saa7134_dev *dev)
unsigned char buf; unsigned char buf;
int board; int board;
/* initialize hardware #2 */ /* Put here the code that enables the chips that are needed
if (TUNER_ABSENT != dev->tuner_type) { for analog mode and doesn't depend on the tuner attachment.
int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); It is also a good idea to get tuner type from eeprom, etc before
initializing tuner, since we can avoid loading tuner driver
/* Note: radio tuner address is always filled in, on devices that has TUNER_ABSENT
so we do not need to probe for a radio tuner device. */ */
if (dev->radio_type != UNSET)
v4l2_i2c_new_subdev(&dev->i2c_adap,
"tuner", "tuner", dev->radio_addr);
if (has_demod)
v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
"tuner", 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_probed_subdev(&dev->i2c_adap, "tuner",
"tuner", v4l2_i2c_tuner_addrs(type));
} else {
v4l2_i2c_new_subdev(&dev->i2c_adap,
"tuner", "tuner", dev->tuner_addr);
}
}
switch (dev->board) { switch (dev->board) {
case SAA7134_BOARD_BMK_MPEX_NOTUNER: case SAA7134_BOARD_BMK_MPEX_NOTUNER:
case SAA7134_BOARD_BMK_MPEX_TUNER: 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; dev->i2c_client.addr = 0x60;
board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0) board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
? SAA7134_BOARD_BMK_MPEX_NOTUNER ? SAA7134_BOARD_BMK_MPEX_NOTUNER
...@@ -6241,11 +6198,15 @@ int saa7134_board_init2(struct saa7134_dev *dev) ...@@ -6241,11 +6198,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
u8 subaddr; u8 subaddr;
u8 data[3]; u8 data[3];
int ret, tuner_t; int ret, tuner_t;
struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1}, struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
{.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}}; {.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
subaddr= 0x14; subaddr= 0x14;
tuner_t = 0; tuner_t = 0;
/* Retrieve device data from eeprom, checking for the
proper tuner_type.
*/
ret = i2c_transfer(&dev->i2c_adap, msg, 2); ret = i2c_transfer(&dev->i2c_adap, msg, 2);
if (ret != 2) { if (ret != 2) {
printk(KERN_ERR "EEPROM read failure\n"); printk(KERN_ERR "EEPROM read failure\n");
...@@ -6301,12 +6262,14 @@ int saa7134_board_init2(struct saa7134_dev *dev) ...@@ -6301,12 +6262,14 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name, saa7134_boards[dev->board].name); dev->name, saa7134_boards[dev->board].name);
break; break;
} }
/* break intentionally omitted */
case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
{ {
/* The Philips EUROPA based hybrid boards have the tuner connected through /* The Philips EUROPA based hybrid boards have the tuner
* the channel decoder. We have to make it transparent to find it connected through the channel decoder. We have to make it
transparent to find it
*/ */
u8 data[] = { 0x07, 0x02}; u8 data[] = { 0x07, 0x02};
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
...@@ -6327,21 +6290,15 @@ int saa7134_board_init2(struct saa7134_dev *dev) ...@@ -6327,21 +6290,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) { if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
dev->tuner_type = TUNER_PHILIPS_TDA8290; dev->tuner_type = TUNER_PHILIPS_TDA8290;
saa7134_tuner_setup(dev);
data[2] = 0x68; data[2] = 0x68;
i2c_transfer(&dev->i2c_adap, &msg, 1); i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
/* Tuner setup is handled before I2C transfer.
Due to that, there's no need to do it later
*/
return 0;
} }
i2c_transfer(&dev->i2c_adap, &msg, 1); i2c_transfer(&dev->i2c_adap, &msg, 1);
break; break;
} }
case SAA7134_BOARD_ASUSTeK_TVFM7135: case SAA7134_BOARD_ASUSTeK_TVFM7135:
/* The card below is detected as card=53, but is different */ /* The card below is detected as card=53, but is different */
if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
printk(KERN_INFO "%s: P7131 analog only, using " printk(KERN_INFO "%s: P7131 analog only, using "
...@@ -6412,9 +6369,9 @@ int saa7134_board_init2(struct saa7134_dev *dev) ...@@ -6412,9 +6369,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
/* Don't do this if the board was specifically selected with an /* Don't do this if the board was specifically selected with an
* insmod option or if we have the default configuration T200*/ * insmod option or if we have the default configuration T200*/
if(!dev->autodetected || (dev->eedata[0x41] == 0xd0)) if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
break; break;
if(dev->eedata[0x41] == 0x02) { if (dev->eedata[0x41] == 0x02) {
/* Reconfigure board as T200A */ /* Reconfigure board as T200A */
dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A; dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
dev->tuner_type = saa7134_boards[dev->board].tuner_type; dev->tuner_type = saa7134_boards[dev->board].tuner_type;
...@@ -6427,6 +6384,58 @@ int saa7134_board_init2(struct saa7134_dev *dev) ...@@ -6427,6 +6384,58 @@ int saa7134_board_init2(struct saa7134_dev *dev)
break; break;
} }
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)
printk(KERN_WARNING
"%s: Unable to enable tuner(%i).\n",
dev->name, i);
}
break;
}
} /* switch() */
/* initialize tuner */
if (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->i2c_adap,
"tuner", "tuner", dev->radio_addr);
if (has_demod)
v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
"tuner", 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_probed_subdev(&dev->i2c_adap, "tuner",
"tuner", v4l2_i2c_tuner_addrs(type));
} else {
v4l2_i2c_new_subdev(&dev->i2c_adap,
"tuner", "tuner", dev->tuner_addr);
}
}
saa7134_tuner_setup(dev);
switch (dev->board) {
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
{ {
struct v4l2_priv_tun_config tea5767_cfg; struct v4l2_priv_tun_config tea5767_cfg;
...@@ -6443,7 +6452,5 @@ int saa7134_board_init2(struct saa7134_dev *dev) ...@@ -6443,7 +6452,5 @@ int saa7134_board_init2(struct saa7134_dev *dev)
} }
} /* switch() */ } /* switch() */
saa7134_tuner_setup(dev);
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment