提交 ef88f2b5 编写于 作者: M Mauro Carvalho Chehab

V4L/DVB (10527): tuner: fix TUV1236D analog/digital setup

As reported by David Engel <david@istwok.net>, ATSC115 doesn't work
fine with mythtv. This software opens both analog and dvb interfaces of
saa7134.

What happens is that some tuner commands are going to the wrong place,
as shown at the logs:

Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: using tuner params #0 (ntsc)
Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: freq = 67.25 (1076), range = 0, config = 0xce, cb = 0x01
Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: Freq= 67.25 MHz, V_IF=45.75 MHz, Offset=0.00 MHz, div=1808
Feb 12 20:37:48 opus kernel: tuner 1-0061: tv freq set to 67.25
Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: using tuner params #0 (ntsc)
Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: freq = 67.25 (1076), range = 0, config = 0xce, cb = 0x01
Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: Freq= 67.25 MHz, V_IF=45.75 MHz, Offset=0.00 MHz, div=1808
Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: tv 0x07 0x10 0xce 0x01
Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: tv 0x07 0x10 0xce 0x01

This happens due to a hack at TUV1236D analog setup, where it replaces
tuner address, at 0x61 for 0x0a, in order to save a few memory bytes.

The code assumes that nobody else would try to access the tuner during
that setup, but the point is that there's no lock to protect such
access. So, this opens the possibility of race conditions to happen.

Instead of hacking tuner address, this patch uses a temporary var with
the proper tuner value to be used during the setup. This should save
the issue, although we should consider to write some analog/digital
lock at saa7134 driver.
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 f63145e2
......@@ -318,7 +318,6 @@ static int simple_std_setup(struct dvb_frontend *fe,
u8 *config, u8 *cb)
{
struct tuner_simple_priv *priv = fe->tuner_priv;
u8 tuneraddr;
int rc;
/* tv norm specific stuff for multi-norm tuners */
......@@ -387,6 +386,7 @@ static int simple_std_setup(struct dvb_frontend *fe,
case TUNER_PHILIPS_TUV1236D:
{
struct tuner_i2c_props i2c = priv->i2c_props;
/* 0x40 -> ATSC antenna input 1 */
/* 0x48 -> ATSC antenna input 2 */
/* 0x00 -> NTSC antenna input 1 */
......@@ -398,17 +398,15 @@ static int simple_std_setup(struct dvb_frontend *fe,
buffer[1] = 0x04;
}
/* set to the correct mode (analog or digital) */
tuneraddr = priv->i2c_props.addr;
priv->i2c_props.addr = 0x0a;
rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2);
i2c.addr = 0x0a;
rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2);
if (2 != rc)
tuner_warn("i2c i/o error: rc == %d "
"(should be 2)\n", rc);
rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2);
rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2);
if (2 != rc)
tuner_warn("i2c i/o error: rc == %d "
"(should be 2)\n", rc);
priv->i2c_props.addr = tuneraddr;
break;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册