diff mbox series

si2157: Add support for Logilink VG0022A.

Message ID 20191002141359.30166-2-gonsolo@gmail.com (mailing list archive)
State New, archived
Headers show
Series si2157: Add support for Logilink VG0022A. | expand

Commit Message

Gon Solo Oct. 2, 2019, 2:13 p.m. UTC
---
 drivers/media/tuners/si2157.c         | 68 +++++++++++++++++----------
 drivers/media/tuners/si2157_priv.h    |  1 +
 drivers/media/usb/dvb-usb-v2/af9035.c | 47 ++++++++++++++++++
 3 files changed, 90 insertions(+), 26 deletions(-)

Comments

Sean Young Oct. 2, 2019, 2:27 p.m. UTC | #1
On Wed, Oct 02, 2019 at 04:13:59PM +0200, Gon Solo wrote:

You need a message and a Signed-off-by: here.

> ---
>  drivers/media/tuners/si2157.c         | 68 +++++++++++++++++----------
>  drivers/media/tuners/si2157_priv.h    |  1 +
>  drivers/media/usb/dvb-usb-v2/af9035.c | 47 ++++++++++++++++++
>  3 files changed, 90 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
> index e87040d6eca7..8f9df2485d51 100644
> --- a/drivers/media/tuners/si2157.c
> +++ b/drivers/media/tuners/si2157.c
> @@ -66,6 +66,24 @@ static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd)
>  	return ret;
>  }
>  
> +static int si2157_power_up(struct si2157_dev *dev, struct i2c_client *client)
> +{
> +	struct si2157_cmd cmd;
> +
> +	if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
> +		memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
> +		cmd.wlen = 9;
> +	} else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
> +		memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
> +		cmd.wlen = 10;
> +	} else {
> +		memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
> +		cmd.wlen = 15;
> +	}
> +	cmd.rlen = 1;
> +	return si2157_cmd_execute(client, &cmd);
> +}
> +
>  static int si2157_init(struct dvb_frontend *fe)
>  {
>  	struct i2c_client *client = fe->tuner_priv;
> @@ -75,7 +93,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  	struct si2157_cmd cmd;
>  	const struct firmware *fw;
>  	const char *fw_name;
> -	unsigned int uitmp, chip_id;
> +	unsigned int uitmp;
>  
>  	dev_dbg(&client->dev, "\n");
>  
> @@ -93,19 +111,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  	if (uitmp == dev->if_frequency / 1000)
>  		goto warm;
>  
> -	/* power up */
> -	if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
> -		memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
> -		cmd.wlen = 9;
> -	} else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
> -		memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
> -		cmd.wlen = 10;
> -	} else {
> -		memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
> -		cmd.wlen = 15;
> -	}
> -	cmd.rlen = 1;
> -	ret = si2157_cmd_execute(client, &cmd);
> +	ret = si2157_power_up(dev, client);
>  	if (ret)
>  		goto err;
>  
> @@ -118,17 +124,6 @@ static int si2157_init(struct dvb_frontend *fe)
>  			goto err;
>  	}
>  
> -	/* query chip revision */
> -	memcpy(cmd.args, "\x02", 1);
> -	cmd.wlen = 1;
> -	cmd.rlen = 13;
> -	ret = si2157_cmd_execute(client, &cmd);
> -	if (ret)
> -		goto err;
> -
> -	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
> -			cmd.args[4] << 0;
> -
>  	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
>  	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
>  	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
> @@ -137,7 +132,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  	#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
>  	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
>  
> -	switch (chip_id) {
> +	switch (dev->chip_id) {
>  	case SI2158_A20:
>  	case SI2148_A20:
>  		fw_name = SI2158_A20_FIRMWARE;
> @@ -456,6 +451,27 @@ static int si2157_probe(struct i2c_client *client,
>  	memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops));
>  	fe->tuner_priv = client;
>  
> +	ret = si2157_power_up(dev, client);
> +	if (ret)
> +		goto err;
> +	/* query chip revision */
> +	/* hack: do it here because after the si2168 gets 0101, commands will
> +	 * still be executed here but no result

I don't understand. What problem are you seeing here? Why can't you do a
query chip revision first?

This needs resolving of course.

> +	 */
> +	memcpy(cmd.args, "\x02", 1);
> +	cmd.wlen = 1;
> +	cmd.rlen = 13;
> +	ret = si2157_cmd_execute(client, &cmd);
> +	if (ret)
> +		goto err_kfree;
> +	dev->chip_id = cmd.args[1] << 24 |
> +		cmd.args[2] << 16 |
> +		cmd.args[3] << 8 |
> +		cmd.args[4] << 0;
> +	dev_info(&client->dev, "found a 'Silicon Labs Si21%d-%c%c%c'\n",
> +		cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
> +
> +
>  #ifdef CONFIG_MEDIA_CONTROLLER
>  	if (cfg->mdev) {
>  		dev->mdev = cfg->mdev;
> diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
> index 2bda903358da..9ab7c88b01b4 100644
> --- a/drivers/media/tuners/si2157_priv.h
> +++ b/drivers/media/tuners/si2157_priv.h
> @@ -28,6 +28,7 @@ struct si2157_dev {
>  	u8 chiptype;
>  	u8 if_port;
>  	u32 if_frequency;
> +	u32 chip_id;
>  	struct delayed_work stat_work;
>  
>  #if defined(CONFIG_MEDIA_CONTROLLER)
> diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
> index 3afd18733614..83e243df59b9 100644
> --- a/drivers/media/usb/dvb-usb-v2/af9035.c
> +++ b/drivers/media/usb/dvb-usb-v2/af9035.c
> @@ -1246,6 +1246,51 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
>  
>  	msleep(200);
>  
> +	if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK) {
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		/* I2C master bus 2 clock speed 300k */
> +		ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
> +		if (ret < 0)
> +			goto err;
> +
> +		/* I2C master bus 1,3 clock speed 300k */
> +		ret = af9035_wr_reg(d, 0x00f103, 0x07);
> +		if (ret < 0)
> +			goto err;
> +
> +		/* set gpio11 low */
> +		ret = af9035_wr_reg_mask(d, 0xd8d4, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8d5, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8d3, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		/* Tuner enable using gpiot2_en, gpiot2_on and gpiot2_o (reset) */
> +		ret = af9035_wr_reg_mask(d, 0xd8b8, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8b9, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		msleep(200);
> +	}
> +
>  	ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01);
>  	if (ret < 0)
>  		goto err;
> @@ -2119,6 +2164,8 @@ static const struct usb_device_id af9035_id_table[] = {
>  	/* IT930x devices */
>  	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
>  		&it930x_props, "ITE 9303 Generic", NULL) },
> +	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
> +		&it930x_props, "Logilink VG0022A", NULL) },
>  	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310,
>  		&it930x_props, "AVerMedia TD310 DVB-T2", NULL) },
>  	{ }
> -- 
> 2.20.1
Gon Solo Oct. 2, 2019, 2:44 p.m. UTC | #2
Hi!

> You need a message and a Signed-off-by: here.

Ok, I'll try to get that right the next time.

> > +     ret = si2157_power_up(dev, client);
> > +     if (ret)
> > +             goto err;
> > +     /* query chip revision */
> > +     /* hack: do it here because after the si2168 gets 0101, commands will
> > +      * still be executed here but no result
>
> I don't understand. What problem are you seeing here? Why can't you do a
> query chip revision first?

This was explained here: https://lkml.org/lkml/2017/3/15/778. To quote:

If the si2157 is behind a e.g. si2168, the si2157 will at least in
some situations not be readable after the si268 got the command 0101.
It still accepts commands but the answer is just ffffff. So read the
chip id before that so the information is not lost.

The following line in kernel output is a symptome of that problem:
si2157 7-0063: unknown chip version Si21255-\xffffffff\xffffffff\xffffffff

> This needs resolving of course.

I hope so. :)

g
Mauro Carvalho Chehab Oct. 2, 2019, 3 p.m. UTC | #3
Em Wed,  2 Oct 2019 16:13:59 +0200
Gon Solo <gonsolo@gmail.com> escreveu:


All patches should have a description at the beginning of the e-mail
body, even the trivial ones.


You also forgot to add your Signed-off-by.

> ---
>  drivers/media/tuners/si2157.c         | 68 +++++++++++++++++----------
>  drivers/media/tuners/si2157_priv.h    |  1 +
>  drivers/media/usb/dvb-usb-v2/af9035.c | 47 ++++++++++++++++++
>  3 files changed, 90 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
> index e87040d6eca7..8f9df2485d51 100644
> --- a/drivers/media/tuners/si2157.c
> +++ b/drivers/media/tuners/si2157.c
> @@ -66,6 +66,24 @@ static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd)
>  	return ret;
>  }
>  
> +static int si2157_power_up(struct si2157_dev *dev, struct i2c_client *client)
> +{
> +	struct si2157_cmd cmd;
> +
> +	if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
> +		memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
> +		cmd.wlen = 9;
> +	} else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
> +		memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
> +		cmd.wlen = 10;
> +	} else {
> +		memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
> +		cmd.wlen = 15;
> +	}
> +	cmd.rlen = 1;
> +	return si2157_cmd_execute(client, &cmd);
> +}
> +
>  static int si2157_init(struct dvb_frontend *fe)
>  {
>  	struct i2c_client *client = fe->tuner_priv;
> @@ -75,7 +93,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  	struct si2157_cmd cmd;
>  	const struct firmware *fw;
>  	const char *fw_name;
> -	unsigned int uitmp, chip_id;
> +	unsigned int uitmp;
>  
>  	dev_dbg(&client->dev, "\n");
>  
> @@ -93,19 +111,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  	if (uitmp == dev->if_frequency / 1000)
>  		goto warm;
>  
> -	/* power up */
> -	if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
> -		memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
> -		cmd.wlen = 9;
> -	} else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
> -		memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
> -		cmd.wlen = 10;
> -	} else {
> -		memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
> -		cmd.wlen = 15;
> -	}
> -	cmd.rlen = 1;
> -	ret = si2157_cmd_execute(client, &cmd);
> +	ret = si2157_power_up(dev, client);
>  	if (ret)
>  		goto err;

Ok, you're moving the power-op code to a function. That's OK, but
the rule is one patch per functional change.

So, the first patch in this series should be the one moving the
power up code to a separate function, e. g. the e-mail would be
something like:

	Subject: [PATCH 1/3] media: si2157: move power up code to a function

	On some devices, we need to power up the device on other places,
	so move the code to a separate function.

	Signed-off-by: your name <your@email>

	...

>  
> @@ -118,17 +124,6 @@ static int si2157_init(struct dvb_frontend *fe)
>  			goto err;
>  	}
>  
> -	/* query chip revision */
> -	memcpy(cmd.args, "\x02", 1);
> -	cmd.wlen = 1;
> -	cmd.rlen = 13;
> -	ret = si2157_cmd_execute(client, &cmd);
> -	if (ret)
> -		goto err;
> -
> -	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
> -			cmd.args[4] << 0;
> -
>  	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
>  	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
>  	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
> @@ -137,7 +132,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  	#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
>  	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
>  
> -	switch (chip_id) {
> +	switch (dev->chip_id) {
>  	case SI2158_A20:
>  	case SI2148_A20:
>  		fw_name = SI2158_A20_FIRMWARE;
> @@ -456,6 +451,27 @@ static int si2157_probe(struct i2c_client *client,
>  	memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops));
>  	fe->tuner_priv = client;
>  
> +	ret = si2157_power_up(dev, client);
> +	if (ret)
> +		goto err;
> +	/* query chip revision */
> +	/* hack: do it here because after the si2168 gets 0101, commands will
> +	 * still be executed here but no result
> +	 */
> +	memcpy(cmd.args, "\x02", 1);
> +	cmd.wlen = 1;
> +	cmd.rlen = 13;
> +	ret = si2157_cmd_execute(client, &cmd);
> +	if (ret)
> +		goto err_kfree;
> +	dev->chip_id = cmd.args[1] << 24 |
> +		cmd.args[2] << 16 |
> +		cmd.args[3] << 8 |
> +		cmd.args[4] << 0;
> +	dev_info(&client->dev, "found a 'Silicon Labs Si21%d-%c%c%c'\n",
> +		cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
> +
> +

Why the extra blank line?

The above code seems to be a separate issue and should be handled
in separate.

I suspect, however, that the issue is actually at the bridge driver.

You should probably open the I2C gate before being able to talk
with it.

>  #ifdef CONFIG_MEDIA_CONTROLLER
>  	if (cfg->mdev) {
>  		dev->mdev = cfg->mdev;
> diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
> index 2bda903358da..9ab7c88b01b4 100644
> --- a/drivers/media/tuners/si2157_priv.h
> +++ b/drivers/media/tuners/si2157_priv.h
> @@ -28,6 +28,7 @@ struct si2157_dev {
>  	u8 chiptype;
>  	u8 if_port;
>  	u32 if_frequency;
> +	u32 chip_id;
>  	struct delayed_work stat_work;
>  
>  #if defined(CONFIG_MEDIA_CONTROLLER)
> diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
> index 3afd18733614..83e243df59b9 100644
> --- a/drivers/media/usb/dvb-usb-v2/af9035.c
> +++ b/drivers/media/usb/dvb-usb-v2/af9035.c
> @@ -1246,6 +1246,51 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
>  
>  	msleep(200);
>  
> +	if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK) {
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		/* I2C master bus 2 clock speed 300k */
> +		ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
> +		if (ret < 0)
> +			goto err;
> +
> +		/* I2C master bus 1,3 clock speed 300k */
> +		ret = af9035_wr_reg(d, 0x00f103, 0x07);
> +		if (ret < 0)
> +			goto err;
> +
> +		/* set gpio11 low */
> +		ret = af9035_wr_reg_mask(d, 0xd8d4, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8d5, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8d3, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		/* Tuner enable using gpiot2_en, gpiot2_on and gpiot2_o (reset) */
> +		ret = af9035_wr_reg_mask(d, 0xd8b8, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8b9, 0x01, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01);
> +		if (ret < 0)
> +			goto err;
> +
> +		msleep(200);

Hmm.... you are setting bit 1 of 0xd8b7 to 0 here...

> +	}
> +
>  	ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01);
>  	if (ret < 0)
>  		goto err;

Then setting it to 1 here.

Is this a reset pin? If so, perhaps you need to do something like:

	ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01);
		if (ret < 0)
			goto err;

	msleep(200);

	ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01);
		if (ret < 0)
			goto err;

	msleep(200);

In order to wait for the reset to finish and be able to talk with the
tuner.


> @@ -2119,6 +2164,8 @@ static const struct usb_device_id af9035_id_table[] = {
>  	/* IT930x devices */
>  	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
>  		&it930x_props, "ITE 9303 Generic", NULL) },
> +	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
> +		&it930x_props, "Logilink VG0022A", NULL) },
>  	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310,
>  		&it930x_props, "AVerMedia TD310 DVB-T2", NULL) },
>  	{ }



Thanks,
Mauro
Sean Young Oct. 2, 2019, 3:06 p.m. UTC | #4
On Wed, Oct 02, 2019 at 04:44:24PM +0200, Gonsolo wrote:
> Hi!
> 
> > You need a message and a Signed-off-by: here.
> 
> Ok, I'll try to get that right the next time.
> 
> > > +     ret = si2157_power_up(dev, client);
> > > +     if (ret)
> > > +             goto err;
> > > +     /* query chip revision */
> > > +     /* hack: do it here because after the si2168 gets 0101, commands will
> > > +      * still be executed here but no result
> >
> > I don't understand. What problem are you seeing here? Why can't you do a
> > query chip revision first?
> 
> This was explained here: https://lkml.org/lkml/2017/3/15/778. To quote:

Antti has some great suggestions in that thread:
	https://lkml.org/lkml/2017/5/24/245

Also note https://lkml.org/lkml/2017/5/26/357 if you have access to a 
logic analyser.


Sean
Gon Solo Oct. 2, 2019, 3:21 p.m. UTC | #5
Hi!

> Antti has some great suggestions in that thread:
>         https://lkml.org/lkml/2017/5/24/245
>
> Also note https://lkml.org/lkml/2017/5/26/357 if you have access to a
> logic analyser.

I read that thread. Unfortunately I'm not a hardware engineer nor do I
have access to a logic analyser, just the device and a remote hope not
to keep my custom 4.13 kernel forever or to have to buy a new DVB T2
device. :(
In the above thread it is mentioned that even the Windows driver
receives the ffff's so maybe it is a hardware bug?

I'd love to see this driver upstream but I have no idea how to
proceed. Any suggestions?
Jan Pieter van Woerkom Oct. 2, 2019, 5:23 p.m. UTC | #6
Hi all.

On 10/2/19 5:21 PM, Gonsolo wrote:
> Hi!
>
>> Antti has some great suggestions in that thread:
>>          https://lkml.org/lkml/2017/5/24/245
>>
>> Also note https://lkml.org/lkml/2017/5/26/357 if you have access to a
>> logic analyser.
> I read that thread. Unfortunately I'm not a hardware engineer nor do I
> have access to a logic analyser, just the device and a remote hope not
> to keep my custom 4.13 kernel forever or to have to buy a new DVB T2
> device. :(
> In the above thread it is mentioned that even the Windows driver
> receives the ffff's so maybe it is a hardware bug?
Looks like it is:
http://lkml.iu.edu/hypermail/linux/kernel/1710.3/03205.html
>
> I'd love to see this driver upstream but I have no idea how to
> proceed. Any suggestions?
>
Mauro Carvalho Chehab Oct. 2, 2019, 6:49 p.m. UTC | #7
Em Wed, 2 Oct 2019 19:23:02 +0200
JP <jp@jpvw.nl> escreveu:

> Hi all.
> 
> On 10/2/19 5:21 PM, Gonsolo wrote:
> > Hi!
> >  
> >> Antti has some great suggestions in that thread:
> >>          https://lkml.org/lkml/2017/5/24/245
> >>
> >> Also note https://lkml.org/lkml/2017/5/26/357 if you have access to a
> >> logic analyser.  
> > I read that thread. Unfortunately I'm not a hardware engineer nor do I
> > have access to a logic analyser, just the device and a remote hope not
> > to keep my custom 4.13 kernel forever or to have to buy a new DVB T2
> > device. :(
> > In the above thread it is mentioned that even the Windows driver
> > receives the ffff's so maybe it is a hardware bug?  
> Looks like it is:
> http://lkml.iu.edu/hypermail/linux/kernel/1710.3/03205.html

Hmm... changing the pull-up register will very likely change the
timings.

There's a logic at the driver that changes the I2C bus speed to
300k (with is non-standard):


		/* I2C master bus 2 clock speed 300k */
		ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
		if (ret < 0)
			goto err;

		/* I2C master bus 1,3 clock speed 300k */
		ret = af9035_wr_reg(d, 0x00f103, 0x07);
		if (ret < 0)
			goto err;

Perhaps if we reduce the bus speed to 100k, the device will work
without the hacks.

I don't have af9035 datasheets. Perhaps Antti could shed some
light about how to change the speed to 100k, but on a quick search 
at the Internet, I found this:

	https://lore.kernel.org/linux-media/1312539895.2763.33.camel@Jason-Linux/

With has a comment that explains how the I2C speed is calculated on those
ITE devices:

	#define    p_reg_one_cycle_counter_tuner	0xF103

	/* Define I2C master speed, the default value 0x07 means 366KHz (1000000000 / (24.4 * 16 * User_I2C_SPEED)). */
	#define User_I2C_SPEED 0x07

	error =
	    it9135_write_reg(data, 0, PROCESSOR_LINK,
			     p_reg_one_cycle_counter_tuner, User_I2C_SPEED);

So, in summary, the value for the I2C speed register is given by:

	I2C_speed_register = (1000000000 / (24.4 * 16 * I2C_speed))

So, for 100 kbps, the I2C speed register should be set with a value
close to ~25,6.

Doing the reverse math, we have:

	I2C_speed_register = 25 -> I2C_speed = 102,46 kbps
	I2C_speed_register = 26 -> I2C_speed = 98,52 kbps

So, if we do:

		/* I2C master bus 2 clock speed ~100k */
		ret = af9035_wr_reg(d, 0x00f6a7, 26);
		if (ret < 0)
			goto err;

		/* I2C master bus 1,3 clock speed ~100k */
		ret = af9035_wr_reg(d, 0x00f103, 26);
		if (ret < 0)
			goto err;

The bus speed will reduce to 98,52 kbps, with is a typical nominal
value for I2C tuners and other devices. With that, the device should 
probably work fine without needing to replace the pull up resistor.

Ok, tuner firmware load would be ~3,7 times slower, but this is
something that we do just once need a firmware). 

All other I2C messages are short enough to not cause any real difference.


Could you please test the enclosing patch and see if, with that, you
can remove the hacks you added for the tuner probe to work?

Regards,
Mauro

[PATCH] media: af9035: slow down I2C bus speed on it930x devices

We have a few reports about tuner probing instability with
some it930x devices.

As it is better safe than sorry, let's slow down the I2C,
using the formula found at an old patch:

https://lore.kernel.org/linux-media/1312539895.2763.33.camel@Jason-Linux/

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 3afd18733614..df2c75b84be8 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -1197,6 +1197,9 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
 	return ret;
 }
 
+/* I2C speed register = (1000000000 / (24.4 * 16 * I2C_speed)) */
+#define I2C_SPEED_REGISTER 26
+
 static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	struct state *state = adap_to_priv(adap);
@@ -1208,13 +1211,13 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
 
 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
 
-	/* I2C master bus 2 clock speed 300k */
-	ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
+	/* I2C master bus 2 clock speed ~100k */
+	ret = af9035_wr_reg(d, 0x00f6a7, I2C_SPEED_REGISTER);
 	if (ret < 0)
 		goto err;
 
-	/* I2C master bus 1,3 clock speed 300k */
-	ret = af9035_wr_reg(d, 0x00f103, 0x07);
+	/* I2C master bus 1,3 clock speed ~100k */
+	ret = af9035_wr_reg(d, 0x00f103, I2C_SPEED_REGISTER);
 	if (ret < 0)
 		goto err;
Gon Solo Oct. 3, 2019, 10:13 a.m. UTC | #8
Hi!

> Could you please test the enclosing patch and see if, with that, you
> can remove the hacks you added for the tuner probe to work?

I tested again on a vanilla media_tree with Mauro's patch attached.
Doesn't work. Dmesg output:

[    0.788387] kernel: usb 1-1: new high-speed USB device number 2
using ehci-pci
[    0.792384] kernel: usb 2-1: new high-speed USB device number 2
using xhci_hcd
[    0.944937] kernel: usb 2-1: New USB device found, idVendor=1d19,
idProduct=0100, bcdDevice= 1.00
[    0.944939] kernel: usb 2-1: New USB device strings: Mfr=1,
Product=2, SerialNumber=3
[    0.944940] kernel: usb 2-1: Product: TS Aggregator
[    0.944941] kernel: usb 2-1: Manufacturer: ITE Tech., Inc.
[    0.944942] kernel: usb 2-1: SerialNumber: AF0102020700001

I then also used the following (additional) patch:

@@ -2119,6 +2122,8 @@ static const struct usb_device_id af9035_id_table[] = {
        /* IT930x devices */
        { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
                &it930x_props, "ITE 9303 Generic", NULL) },
+       { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
+               &it930x_props, "Logilink VG0022A", NULL) },
        { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310,
                &it930x_props, "AVerMedia TD310 DVB-T2", NULL) },
        { }

Which gives the following output:

[    5.380989] si2168 1-0067: Silicon Labs Si2168-B40 successfully identified
[    5.380991] si2168 1-0067: firmware version: B 4.0.2
[    5.381013] usb 2-1: DVB: registering adapter 0 frontend 0 (Silicon
Labs Si2168)...
[    5.381018] dvbdev: dvb_create_media_entity: media entity 'Silicon
Labs Si2168' registered.
[    5.390058] checking generic (e0000000 410000) vs hw (e0000000 10000000)
[    5.390062] fb0: switching to inteldrmfb from EFI VGA
[    5.390268] Console: switching to colour dummy device 80x25
[    5.390281] i915 0000:00:02.0: vgaarb: deactivate vga console
[    5.393438] si2157 2-0063: Silicon Labs Si2147/2148/2157/2158
successfully attached

But when I try to use VLC I get the following:

[  457.677363] si2168 1-0067: downloading firmware from file
'dvb-demod-si2168-b40-01.fw'
[  458.631034] si2168 1-0067: firmware version: B 4.0.11
[  458.650309] si2157 2-0063: unknown chip version Si21255-\xff\xff\xff

Now I'm trying other timings.

Thanks,
g
Gon Solo Oct. 3, 2019, 10:57 a.m. UTC | #9
Hi!

Boot time:

> [    5.380991] si2168 1-0067: firmware version: B 4.0.2

When starting VLC:

> [  457.677363] si2168 1-0067: downloading firmware from file
> 'dvb-demod-si2168-b40-01.fw'
> [  458.631034] si2168 1-0067: firmware version: B 4.0.11
> [  458.650309] si2157 2-0063: unknown chip version Si21255-\xff\xff\xff

There are two different firmware versions, 4.0.2 and 4.0.11. Is that expected?
Mauro Carvalho Chehab Oct. 3, 2019, 11:05 a.m. UTC | #10
Em Thu, 3 Oct 2019 12:13:33 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> Hi!
> 
> > Could you please test the enclosing patch and see if, with that, you
> > can remove the hacks you added for the tuner probe to work?  
> 
> I tested again on a vanilla media_tree with Mauro's patch attached.
> Doesn't work. Dmesg output:
> 
> [    0.788387] kernel: usb 1-1: new high-speed USB device number 2
> using ehci-pci
> [    0.792384] kernel: usb 2-1: new high-speed USB device number 2
> using xhci_hcd
> [    0.944937] kernel: usb 2-1: New USB device found, idVendor=1d19,
> idProduct=0100, bcdDevice= 1.00
> [    0.944939] kernel: usb 2-1: New USB device strings: Mfr=1,
> Product=2, SerialNumber=3
> [    0.944940] kernel: usb 2-1: Product: TS Aggregator
> [    0.944941] kernel: usb 2-1: Manufacturer: ITE Tech., Inc.
> [    0.944942] kernel: usb 2-1: SerialNumber: AF0102020700001
> 
> I then also used the following (additional) patch:
> 
> @@ -2119,6 +2122,8 @@ static const struct usb_device_id af9035_id_table[] = {
>         /* IT930x devices */
>         { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
>                 &it930x_props, "ITE 9303 Generic", NULL) },
> +       { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
> +               &it930x_props, "Logilink VG0022A", NULL) },
>         { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310,
>                 &it930x_props, "AVerMedia TD310 DVB-T2", NULL) },
>         { }
> 
> Which gives the following output:
> 
> [    5.380989] si2168 1-0067: Silicon Labs Si2168-B40 successfully identified
> [    5.380991] si2168 1-0067: firmware version: B 4.0.2
> [    5.381013] usb 2-1: DVB: registering adapter 0 frontend 0 (Silicon
> Labs Si2168)...
> [    5.381018] dvbdev: dvb_create_media_entity: media entity 'Silicon
> Labs Si2168' registered.
> [    5.390058] checking generic (e0000000 410000) vs hw (e0000000 10000000)
> [    5.390062] fb0: switching to inteldrmfb from EFI VGA
> [    5.390268] Console: switching to colour dummy device 80x25
> [    5.390281] i915 0000:00:02.0: vgaarb: deactivate vga console
> [    5.393438] si2157 2-0063: Silicon Labs Si2147/2148/2157/2158
> successfully attached

Ok. It sounds that the issues you're facing are indeed related to timing
conditions.

> 
> But when I try to use VLC I get the following:
> 
> [  457.677363] si2168 1-0067: downloading firmware from file
> 'dvb-demod-si2168-b40-01.fw'
> [  458.631034] si2168 1-0067: firmware version: B 4.0.11
> [  458.650309] si2157 2-0063: unknown chip version Si21255-\xff\xff\xff
> 
> Now I'm trying other timings.

Returning 0xff, 0xff, 0xff, ... usually means that the tuner chip didn't
respond in time.

This could indicate:

1) The device requires more time to go to sane state after firmware
   load and/or device reset/power up;

2) Tuner may be using I2C clock stretching, but the bridge doesn't
   support it.

3) The clock used at the I2C bus is still too high;

4) The tuner is hidden by an I2C gate. 


I think that using the standard I2C bus clock of 100kbps should be
enough.

I2C clock stretching seems to be unlikely for a command that it is
just getting the device's version.

What seems more likely is that this device may need some time after
firmware load to start working.

So, I would add a msleep() somewhere after the firmware update.

Thanks,
Mauro
Mauro Carvalho Chehab Oct. 3, 2019, 11:17 a.m. UTC | #11
Em Thu, 3 Oct 2019 12:57:50 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> Hi!
> 
> Boot time:
> 
> > [    5.380991] si2168 1-0067: firmware version: B 4.0.2  
> 
> When starting VLC:
> 
> > [  457.677363] si2168 1-0067: downloading firmware from file
> > 'dvb-demod-si2168-b40-01.fw'
> > [  458.631034] si2168 1-0067: firmware version: B 4.0.11
> > [  458.650309] si2157 2-0063: unknown chip version Si21255-\xff\xff\xff  
> 
> There are two different firmware versions, 4.0.2 and 4.0.11. Is that expected?

It means that there's a firmware stored at the device's eeprom
(version 4.0.2). When the driver starts, it downloads a newer firmware
from the file dvb-demod-si2168-b40-01.fw.

Btw, could you please try the enclosed hack and post the results?

Thanks,
Mauro

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index e87040d6eca7..3ccfd602934b 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -76,6 +76,7 @@ static int si2157_init(struct dvb_frontend *fe)
 	const struct firmware *fw;
 	const char *fw_name;
 	unsigned int uitmp, chip_id;
+	int i;
 
 	dev_dbg(&client->dev, "\n");
 
@@ -118,16 +119,32 @@ static int si2157_init(struct dvb_frontend *fe)
 			goto err;
 	}
 
-	/* query chip revision */
-	memcpy(cmd.args, "\x02", 1);
-	cmd.wlen = 1;
-	cmd.rlen = 13;
-	ret = si2157_cmd_execute(client, &cmd);
-	if (ret)
-		goto err;
+	for (i = 0; i < 10; i++) {
+		/* query chip revision */
+		memcpy(cmd.args, "\x02", 1);
+		cmd.wlen = 1;
+		cmd.rlen = 13;
+		ret = si2157_cmd_execute(client, &cmd);
+		if (ret)
+			goto err;
+
+		chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
+			  cmd.args[4] << 0;
 
-	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
-			cmd.args[4] << 0;
+		if (chip_id != 0xffffffff)
+			break;
+
+		msleep(10);
+	}
+
+	if (i)
+		dev_info(&client->dev, "Needed to wait %i ms to get chip version", i * 10);
+
+	if (chip_id == 0xffffffff) {
+		dev_err(&client->dev, "Unable to retrieve chip version\n");
+		ret = -EINVAL;
+		goto err;
+	}
 
 	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
 	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
Gon Solo Oct. 3, 2019, 11:41 a.m. UTC | #12
Hi!

> It means that there's a firmware stored at the device's eeprom
> (version 4.0.2). When the driver starts, it downloads a newer firmware
> from the file dvb-demod-si2168-b40-01.fw.

Thanks for the explanation.

> Btw, could you please try the enclosed hack and post the results?

Will do in a second.

FWIW, this hack worked:

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index e87040d6eca7..28a3a4f1640e 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -136,6 +136,7 @@ static int si2157_init(struct dvb_frontend *fe)
        #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
        #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
        #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
+       #define GONZO     (255 << 24 | 255 << 16 | 255 << 8 | 255 << 0)

        switch (chip_id) {
        case SI2158_A20:
@@ -148,6 +149,10 @@ static int si2157_init(struct dvb_frontend *fe)
        case SI2177_A30:
                fw_name = SI2157_A30_FIRMWARE;
                break;
+       case GONZO:
+               dev_info(&client->dev, "trying null\n");
+               fw_name = NULL;
+               break;
        case SI2157_A30:
        case SI2147_A30:
        case SI2146_A10:
Gon Solo Oct. 3, 2019, 12:01 p.m. UTC | #13
Hi!

 
> Btw, could you please try the enclosed hack and post the results?
 
[  210.178948] si2168 1-0067: downloading firmware from file 'dvb-demod-si2168-b40-01.fw'
[  212.404011] si2168 1-0067: firmware version: B 4.0.25
[  212.656467] si2157 2-0063: Needed to wait 100 ms to get chip version
[  212.656470] si2157 2-0063: Unable to retrieve chip version

:(

g
Mauro Carvalho Chehab Oct. 3, 2019, 12:12 p.m. UTC | #14
Em Thu, 3 Oct 2019 14:01:43 +0200
Gon Solo <gonsolo@gmail.com> escreveu:

> Hi!
> 
>  
> > Btw, could you please try the enclosed hack and post the results?  
>  
> [  210.178948] si2168 1-0067: downloading firmware from file 'dvb-demod-si2168-b40-01.fw'
> [  212.404011] si2168 1-0067: firmware version: B 4.0.25
> [  212.656467] si2157 2-0063: Needed to wait 100 ms to get chip version
> [  212.656470] si2157 2-0063: Unable to retrieve chip version

well, you could try to increase the timeout - although 100 ms seems a lot
of time to me.

Thanks,
Mauro
Gon Solo Oct. 3, 2019, 12:20 p.m. UTC | #15
> well, you could try to increase the timeout - although 100 ms seems a lot
> of time to me.

I tried 5s, still no change.

Would it be possible to include my patch, possibly with a warning like
"bogus chip version, trying with no firmware"?

g
Mauro Carvalho Chehab Oct. 3, 2019, 12:49 p.m. UTC | #16
Em Thu, 3 Oct 2019 13:41:23 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> Hi!
> 
> > It means that there's a firmware stored at the device's eeprom
> > (version 4.0.2). When the driver starts, it downloads a newer firmware
> > from the file dvb-demod-si2168-b40-01.fw.  
> 
> Thanks for the explanation.
> 
> > Btw, could you please try the enclosed hack and post the results?  
> 
> Will do in a second.
> 
> FWIW, this hack worked:
> 
> diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
> index e87040d6eca7..28a3a4f1640e 100644
> --- a/drivers/media/tuners/si2157.c
> +++ b/drivers/media/tuners/si2157.c
> @@ -136,6 +136,7 @@ static int si2157_init(struct dvb_frontend *fe)
>         #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
>         #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
>         #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
> +       #define GONZO     (255 << 24 | 255 << 16 | 255 << 8 | 255 << 0)
> 
>         switch (chip_id) {
>         case SI2158_A20:
> @@ -148,6 +149,10 @@ static int si2157_init(struct dvb_frontend *fe)
>         case SI2177_A30:
>                 fw_name = SI2157_A30_FIRMWARE;
>                 break;
> +       case GONZO:
> +               dev_info(&client->dev, "trying null\n");
> +               fw_name = NULL;
> +               break;
>         case SI2157_A30:
>         case SI2147_A30:
>         case SI2146_A10:

What does it print with this hack?

Also, could you get the SI version after the reset code at
skip_fw_download, just after retrieving si2157 firmware version?

Thanks,
Mauro
Mauro Carvalho Chehab Oct. 3, 2019, 12:52 p.m. UTC | #17
Em Thu, 3 Oct 2019 09:49:04 -0300
Mauro Carvalho Chehab <mchehab+samsung@kernel.org> escreveu:

> Em Thu, 3 Oct 2019 13:41:23 +0200
> Gonsolo <gonsolo@gmail.com> escreveu:
> 
> > Hi!
> >   
> > > It means that there's a firmware stored at the device's eeprom
> > > (version 4.0.2). When the driver starts, it downloads a newer firmware
> > > from the file dvb-demod-si2168-b40-01.fw.    
> > 
> > Thanks for the explanation.
> >   
> > > Btw, could you please try the enclosed hack and post the results?    
> > 
> > Will do in a second.
> > 
> > FWIW, this hack worked:
> > 
> > diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
> > index e87040d6eca7..28a3a4f1640e 100644
> > --- a/drivers/media/tuners/si2157.c
> > +++ b/drivers/media/tuners/si2157.c
> > @@ -136,6 +136,7 @@ static int si2157_init(struct dvb_frontend *fe)
> >         #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
> >         #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
> >         #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
> > +       #define GONZO     (255 << 24 | 255 << 16 | 255 << 8 | 255 << 0)
> > 
> >         switch (chip_id) {
> >         case SI2158_A20:
> > @@ -148,6 +149,10 @@ static int si2157_init(struct dvb_frontend *fe)
> >         case SI2177_A30:
> >                 fw_name = SI2157_A30_FIRMWARE;
> >                 break;
> > +       case GONZO:
> > +               dev_info(&client->dev, "trying null\n");
> > +               fw_name = NULL;
> > +               break;
> >         case SI2157_A30:
> >         case SI2147_A30:
> >         case SI2146_A10:  
> 
> What does it print with this hack?
> 
> Also, could you get the SI version after the reset code at
> skip_fw_download, just after retrieving si2157 firmware version?

Maybe something like this would make it work?

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index e87040d6eca7..86d945fd50b9 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -129,6 +129,28 @@ static int si2157_init(struct dvb_frontend *fe)
 	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
 			cmd.args[4] << 0;
 
+	if (chip_id == 0xffffffff) {
+		/* reboot the tuner  */
+		memcpy(cmd.args, "\x01\x01", 2);
+		cmd.wlen = 2;
+		cmd.rlen = 1;
+		ret = si2157_cmd_execute(client, &cmd);
+		if (ret)
+			goto err;
+
+		/* query chip revision */
+		memcpy(cmd.args, "\x02", 1);
+		cmd.wlen = 1;
+		cmd.rlen = 13;
+		ret = si2157_cmd_execute(client, &cmd);
+		if (ret)
+			goto err;
+
+		chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
+				cmd.args[4] << 0;
+
+	}
+
 	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
 	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
 	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)


Thanks,
Mauro
Gon Solo Oct. 3, 2019, 1:02 p.m. UTC | #18
> Maybe something like this would make it work?

Nope. :(

[   47.371022] si2168 1-0067: downloading firmware from file 'dvb-demod-si2168-b40-01.fw'
[   48.632824] si2168 1-0067: firmware version: B 4.0.25
[   48.671268] si2157 2-0063: unknown chip version Si21255-\xff\xff\xff


g
Gon Solo Oct. 3, 2019, 1:53 p.m. UTC | #19
Hi!

I tried downloading a new firmware via

       case SI_BOGUS:
-               dev_info(&client->dev, "Bogus chip version, trying
with no firmware\n");
-               fw_name = NULL;
+               dev_info(&client->dev, "Bogus chip version, trying
with new firmware\n");
+               fw_name = SI2157_A30_FIRMWARE;
                break;

which I downloaded from

+               //
https://github.com/CoreELEC/dvb-firmware/blob/master/firmware/dvb-tuner-si2157-a30-01.fw

resulting in

[  209.312086] si2168 1-0067: downloading firmware from file
'dvb-demod-si2168-b40-01.fw'
[  211.535097] si2168 1-0067: firmware version: B 4.0.25
[  211.554938] si2157 2-0063: Bogus chip version, trying with new firmware
[  211.554944] si2157 2-0063: found a 'Silicon Labs Si21255-\xff\xff\xff'
[  211.557978] si2157 2-0063: downloading firmware from file
'dvb-tuner-si2157-a30-01.fw'
[  215.739092] si2157 2-0063: rebooting tuner...
[  215.755271] si2157 2-0063: querying firmware version...
[  215.760756] si2157 2-0063: firmware version: \xff.\xff.255

. So even with a new firmware the queried numbers are bogus.

g
Mauro Carvalho Chehab Oct. 3, 2019, 2:05 p.m. UTC | #20
Em Thu, 3 Oct 2019 15:53:30 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> Hi!
> 
> I tried downloading a new firmware via
> 
>        case SI_BOGUS:
> -               dev_info(&client->dev, "Bogus chip version, trying
> with no firmware\n");
> -               fw_name = NULL;
> +               dev_info(&client->dev, "Bogus chip version, trying
> with new firmware\n");
> +               fw_name = SI2157_A30_FIRMWARE;
>                 break;
> 
> which I downloaded from
> 
> +               //
> https://github.com/CoreELEC/dvb-firmware/blob/master/firmware/dvb-tuner-si2157-a30-01.fw
> 
> resulting in
> 
> [  209.312086] si2168 1-0067: downloading firmware from file
> 'dvb-demod-si2168-b40-01.fw'
> [  211.535097] si2168 1-0067: firmware version: B 4.0.25
> [  211.554938] si2157 2-0063: Bogus chip version, trying with new firmware
> [  211.554944] si2157 2-0063: found a 'Silicon Labs Si21255-\xff\xff\xff'
> [  211.557978] si2157 2-0063: downloading firmware from file
> 'dvb-tuner-si2157-a30-01.fw'
> [  215.739092] si2157 2-0063: rebooting tuner...
> [  215.755271] si2157 2-0063: querying firmware version...
> [  215.760756] si2157 2-0063: firmware version: \xff.\xff.255
> 
> . So even with a new firmware the queried numbers are bogus.

Try to reduce the bus speed to 10kbps
> 
> g



Thanks,
Mauro
Gon Solo Oct. 3, 2019, 2:29 p.m. UTC | #21
> Try to reduce the bus speed to 10kbps

Nope:

#define I2C_SPEED_REGISTER 260  // ~10k

[  117.860961] si2168 1-0067: downloading firmware from file
'dvb-demod-si2168-b40-01.fw'
[  118.958355] si2168 1-0067: firmware version: B 4.0.25
[  118.968882] si2157 2-0063: Bogus chip version, trying with new firmware
[  118.968888] si2157 2-0063: found a 'Silicon Labs Si21255-\xff\xff\xff'
[  118.972005] si2157 2-0063: downloading firmware from file
'dvb-tuner-si2157-a30-01.fw'
[  121.154130] si2157 2-0063: rebooting tuner...
[  121.169626] si2157 2-0063: querying firmware version...
[  121.172799] si2157 2-0063: firmware version: \xff.\xff.255
[  121.172803] si2157 2-0063: querying chip revision...
[  121.175911] si2157 2-0063: chip revision: 255.255.255.255

g
Gon Solo Oct. 3, 2019, 3 p.m. UTC | #22
> So, I would add a msleep() somewhere after the firmware update.

I tried that to no avail:

        release_firmware(fw);
+       msleep(1000);

[  107.903918] si2157 2-0063: firmware version: \xff.\xff.255
[  107.903920] si2157 2-0063: querying chip revision...
[  107.906970] si2157 2-0063: chip revision: 255.255.255.255
Mauro Carvalho Chehab Oct. 3, 2019, 3:02 p.m. UTC | #23
Em Thu, 3 Oct 2019 17:00:08 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> > So, I would add a msleep() somewhere after the firmware update.  
> 
> I tried that to no avail:
> 
>         release_firmware(fw);
> +       msleep(1000);
> 
> [  107.903918] si2157 2-0063: firmware version: \xff.\xff.255
> [  107.903920] si2157 2-0063: querying chip revision...
> [  107.906970] si2157 2-0063: chip revision: 255.255.255.255
> 

With the original patch you proposed, what are the logs?


Thanks,
Mauro
Gon Solo Oct. 3, 2019, 3:17 p.m. UTC | #24
> With the original patch you proposed, what are the logs?

Which one do you mean? That one:

+       case SI_BOGUS:
+               dev_info(&client->dev, "Bogus chip version, trying
with no firmware\n");
+               fw_name = NULL;
+               break;

With this patch VLC is running but the chip revision number and
firmware version are still bogus.

Which means if you receive 0xffffffff you can force no firmware and it runs.
Gon Solo Oct. 3, 2019, 4:03 p.m. UTC | #25
> With the original patch you proposed, what are the logs?

With the following patch applied to media_tree master:

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index e87040d6eca7..4c1ab0b6876a 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -129,13 +129,14 @@ static int si2157_init(struct dvb_frontend *fe)
 	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
 			cmd.args[4] << 0;
 
-	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
-	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
-	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
-	#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
-	#define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
-	#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
-	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
+	#define SI2177_A30 ('A' << 24 |  77 << 16 | '3' << 8 | '0' << 0)
+	#define SI2158_A20 ('A' << 24 |  58 << 16 | '2' << 8 | '0' << 0)
+	#define SI2148_A20 ('A' << 24 |  48 << 16 | '2' << 8 | '0' << 0)
+	#define SI2157_A30 ('A' << 24 |  57 << 16 | '3' << 8 | '0' << 0)
+	#define SI2147_A30 ('A' << 24 |  47 << 16 | '3' << 8 | '0' << 0)
+	#define SI2146_A10 ('A' << 24 |  46 << 16 | '1' << 8 | '0' << 0)
+	#define SI2141_A10 ('A' << 24 |  41 << 16 | '1' << 8 | '0' << 0)
+	#define SI_BOGUS   (255 << 24 | 255 << 16 | 255 << 8 | 255 << 0)
 
 	switch (chip_id) {
 	case SI2158_A20:
@@ -148,6 +149,10 @@ static int si2157_init(struct dvb_frontend *fe)
 	case SI2177_A30:
 		fw_name = SI2157_A30_FIRMWARE;
 		break;
+	case SI_BOGUS:
+		dev_info(&client->dev, "Bogus chip version, trying with no firmware\n");
+		fw_name = NULL;
+		break;
 	case SI2157_A30:
 	case SI2147_A30:
 	case SI2146_A10:
@@ -225,6 +230,7 @@ static int si2157_init(struct dvb_frontend *fe)
 
 	dev_info(&client->dev, "firmware version: %c.%c.%d\n",
 			cmd.args[6], cmd.args[7], cmd.args[8]);
 warm:
 	/* init statistics in order signal app which are supported */
 	c->strength.len = 1;
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 3afd18733614..a8d59cf06b1e 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -1197,6 +1197,11 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
 	return ret;
 }
 
+/* I2C speed register = (1000000000 / (24.4 * 16 * I2C_speed))
+ * 7 equals ~400k, 26 ~100k and 260 ~10k.
+ * */
+#define I2C_SPEED_REGISTER 7
+
 static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	struct state *state = adap_to_priv(adap);
@@ -1208,13 +1213,13 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
 
 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
 
-	/* I2C master bus 2 clock speed 300k */
-	ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
+	/* I2C master bus 2 clock speed */
+	ret = af9035_wr_reg(d, 0x00f6a7, I2C_SPEED_REGISTER);
 	if (ret < 0)
 		goto err;
 
-	/* I2C master bus 1,3 clock speed 300k */
-	ret = af9035_wr_reg(d, 0x00f103, 0x07);
+	/* I2C master bus 1,3 clock speed */
+	ret = af9035_wr_reg(d, 0x00f103, I2C_SPEED_REGISTER);
 	if (ret < 0)
 		goto err;
 
@@ -2119,6 +2124,8 @@ static const struct usb_device_id af9035_id_table[] = {
 	/* IT930x devices */
 	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
 		&it930x_props, "ITE 9303 Generic", NULL) },
+	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
+		&it930x_props, "Logilink VG0022A", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310,
 		&it930x_props, "AVerMedia TD310 DVB-T2", NULL) },
 	{ }

the Messages at boot time are

[    4.262882] si2168 1-0067: Silicon Labs Si2168-B40 successfully identified
[    4.262884] si2168 1-0067: firmware version: B 4.0.2
[    4.262902] usb 2-1: DVB: registering adapter 0 frontend 0 (Silicon Labs Si2168)...
[    4.262908] dvbdev: dvb_create_media_entity: media entity 'Silicon Labs Si2168' registered.
[    4.289776] si2157 2-0063: Silicon Labs Si2147/2148/2157/2158 successfully attached

and the messages when running vlc (successfully) are

[  486.537128] si2168 1-0067: downloading firmware from file 'dvb-demod-si2168-b40-01.fw'
[  487.795436] si2168 1-0067: firmware version: B 4.0.25
[  487.807614] si2157 2-0063: Bogus chip version, trying with no firmware
[  487.807618] si2157 2-0063: found a 'Silicon Labs Si21255-\xff\xff\xff'
[  487.833876] si2157 2-0063: firmware version: \xff.\xff.255

g
Mauro Carvalho Chehab Oct. 3, 2019, 4:09 p.m. UTC | #26
Em Thu, 3 Oct 2019 18:03:36 +0200
Gon Solo <gonsolo@gmail.com> escreveu:

> > With the original patch you proposed, what are the logs?  
> 
> With the following patch applied to media_tree master:
> 
> diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
> index e87040d6eca7..4c1ab0b6876a 100644
> --- a/drivers/media/tuners/si2157.c
> +++ b/drivers/media/tuners/si2157.c
> @@ -129,13 +129,14 @@ static int si2157_init(struct dvb_frontend *fe)
>  	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
>  			cmd.args[4] << 0;
>  
> -	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
> -	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
> -	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
> -	#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
> -	#define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
> -	#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
> -	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
> +	#define SI2177_A30 ('A' << 24 |  77 << 16 | '3' << 8 | '0' << 0)
> +	#define SI2158_A20 ('A' << 24 |  58 << 16 | '2' << 8 | '0' << 0)
> +	#define SI2148_A20 ('A' << 24 |  48 << 16 | '2' << 8 | '0' << 0)
> +	#define SI2157_A30 ('A' << 24 |  57 << 16 | '3' << 8 | '0' << 0)
> +	#define SI2147_A30 ('A' << 24 |  47 << 16 | '3' << 8 | '0' << 0)
> +	#define SI2146_A10 ('A' << 24 |  46 << 16 | '1' << 8 | '0' << 0)
> +	#define SI2141_A10 ('A' << 24 |  41 << 16 | '1' << 8 | '0' << 0)
> +	#define SI_BOGUS   (255 << 24 | 255 << 16 | 255 << 8 | 255 << 0)
>  
>  	switch (chip_id) {
>  	case SI2158_A20:
> @@ -148,6 +149,10 @@ static int si2157_init(struct dvb_frontend *fe)
>  	case SI2177_A30:
>  		fw_name = SI2157_A30_FIRMWARE;
>  		break;
> +	case SI_BOGUS:
> +		dev_info(&client->dev, "Bogus chip version, trying with no firmware\n");
> +		fw_name = NULL;
> +		break;
>  	case SI2157_A30:
>  	case SI2147_A30:
>  	case SI2146_A10:
> @@ -225,6 +230,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  
>  	dev_info(&client->dev, "firmware version: %c.%c.%d\n",
>  			cmd.args[6], cmd.args[7], cmd.args[8]);
>  warm:
>  	/* init statistics in order signal app which are supported */
>  	c->strength.len = 1;
> diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
> index 3afd18733614..a8d59cf06b1e 100644
> --- a/drivers/media/usb/dvb-usb-v2/af9035.c
> +++ b/drivers/media/usb/dvb-usb-v2/af9035.c
> @@ -1197,6 +1197,11 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
>  	return ret;
>  }
>  
> +/* I2C speed register = (1000000000 / (24.4 * 16 * I2C_speed))
> + * 7 equals ~400k, 26 ~100k and 260 ~10k.
> + * */
> +#define I2C_SPEED_REGISTER 7
> +
>  static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
>  {
>  	struct state *state = adap_to_priv(adap);
> @@ -1208,13 +1213,13 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
>  
>  	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
>  
> -	/* I2C master bus 2 clock speed 300k */
> -	ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
> +	/* I2C master bus 2 clock speed */
> +	ret = af9035_wr_reg(d, 0x00f6a7, I2C_SPEED_REGISTER);
>  	if (ret < 0)
>  		goto err;
>  
> -	/* I2C master bus 1,3 clock speed 300k */
> -	ret = af9035_wr_reg(d, 0x00f103, 0x07);
> +	/* I2C master bus 1,3 clock speed */
> +	ret = af9035_wr_reg(d, 0x00f103, I2C_SPEED_REGISTER);
>  	if (ret < 0)
>  		goto err;
>  
> @@ -2119,6 +2124,8 @@ static const struct usb_device_id af9035_id_table[] = {
>  	/* IT930x devices */
>  	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
>  		&it930x_props, "ITE 9303 Generic", NULL) },
> +	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
> +		&it930x_props, "Logilink VG0022A", NULL) },
>  	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310,
>  		&it930x_props, "AVerMedia TD310 DVB-T2", NULL) },
>  	{ }
> 
> the Messages at boot time are
> 
> [    4.262882] si2168 1-0067: Silicon Labs Si2168-B40 successfully identified
> [    4.262884] si2168 1-0067: firmware version: B 4.0.2
> [    4.262902] usb 2-1: DVB: registering adapter 0 frontend 0 (Silicon Labs Si2168)...
> [    4.262908] dvbdev: dvb_create_media_entity: media entity 'Silicon Labs Si2168' registered.
> [    4.289776] si2157 2-0063: Silicon Labs Si2147/2148/2157/2158 successfully attached
> 
> and the messages when running vlc (successfully) are
> 
> [  486.537128] si2168 1-0067: downloading firmware from file 'dvb-demod-si2168-b40-01.fw'
> [  487.795436] si2168 1-0067: firmware version: B 4.0.25
> [  487.807614] si2157 2-0063: Bogus chip version, trying with no firmware
> [  487.807618] si2157 2-0063: found a 'Silicon Labs Si21255-\xff\xff\xff'
> [  487.833876] si2157 2-0063: firmware version: \xff.\xff.255

No, I mean with the first patch you sent to the ML, with the powerup
hack.


Thanks,
Mauro
Gon Solo Oct. 3, 2019, 4:23 p.m. UTC | #27
> No, I mean with the first patch you sent to the ML, with the powerup
> hack.

Boot time:

[    4.653257] si2168 1-0067: Silicon Labs Si2168-B40 successfully identified
[    4.653259] si2168 1-0067: firmware version: B 4.0.2
[    4.653279] usb 2-1: DVB: registering adapter 0 frontend 0 (Silicon Labs Si2168)...
[    4.653284] dvbdev: dvb_create_media_entity: media entity 'Silicon Labs Si2168' registered.
...
[    4.694785] si2157 2-0063: found a 'Silicon Labs Si2147-A30'
[    4.694787] si2157 2-0063: Silicon Labs Si2147/2148/2157/2158 successfully attached
[    4.717814] usb 2-1: dvb_usb_v2: 'Logilink VG0022A' successfully initialized and connected
[    4.717880] usbcore: registered new interface driver dvb_usb_af9035

VLC time:

[  175.490609] si2168 1-0067: downloading firmware from file 'dvb-demod-si2168-b40-01.fw'
[  176.746585] si2168 1-0067: firmware version: B 4.0.25
[  176.781570] si2157 2-0063: firmware version: \xff.\xff.255

g
Mauro Carvalho Chehab Oct. 3, 2019, 5:42 p.m. UTC | #28
Em Thu, 3 Oct 2019 18:23:26 +0200
Gon Solo <gonsolo@gmail.com> escreveu:

> > No, I mean with the first patch you sent to the ML, with the powerup
> > hack.  
> 
> Boot time:
> 
> [    4.653257] si2168 1-0067: Silicon Labs Si2168-B40 successfully identified
> [    4.653259] si2168 1-0067: firmware version: B 4.0.2
> [    4.653279] usb 2-1: DVB: registering adapter 0 frontend 0 (Silicon Labs Si2168)...
> [    4.653284] dvbdev: dvb_create_media_entity: media entity 'Silicon Labs Si2168' registered.
> ...
> [    4.694785] si2157 2-0063: found a 'Silicon Labs Si2147-A30'
> [    4.694787] si2157 2-0063: Silicon Labs Si2147/2148/2157/2158 successfully attached
> [    4.717814] usb 2-1: dvb_usb_v2: 'Logilink VG0022A' successfully initialized and connected
> [    4.717880] usbcore: registered new interface driver dvb_usb_af9035
> 
> VLC time:
> 
> [  175.490609] si2168 1-0067: downloading firmware from file 'dvb-demod-si2168-b40-01.fw'
> [  176.746585] si2168 1-0067: firmware version: B 4.0.25
> [  176.781570] si2157 2-0063: firmware version: \xff.\xff.255

Weird... it sounds that, after si2168 has its firmware updated, it
starts interfering at si2157. Perhaps there's a bug at si2168 I2C
gate mux logic. Are you using a new Kernel like 5.2?

I guess the best is to enable the debug logs in order to see what's
happening on both cases.

You can enable all debug messages (after loading the modules) with:

	# for i in $(cat /sys/kernel/debug/dynamic_debug/control |grep -E '(si21|af9035)' |cut -d' ' -f 1); do echo "file $i +p" >>/sys/kernel/debug/dynamic_debug/control; done

You could also try to disable the firmware upload at si2168 and see
if the si2157 reads will succeed.


Thanks,
Mauro
Gon Solo Oct. 3, 2019, 5:49 p.m. UTC | #29
> Weird... it sounds that, after si2168 has its firmware updated, it
> starts interfering at si2157. Perhaps there's a bug at si2168 I2C
> gate mux logic. Are you using a new Kernel like 5.2?

Everything is based on git://linuxtv.org/media_tree.git which is at
5.4-rc1 right now.

> I guess the best is to enable the debug logs in order to see what's
> happening on both cases.
>
> You can enable all debug messages (after loading the modules) with:
>
>         # for i in $(cat /sys/kernel/debug/dynamic_debug/control |grep -E '(si21|af9035)' |cut -d' ' -f 1); do echo "file $i +p" >>/sys/kernel/debug/dynamic_debug/control; done

I'll give that a try.

> You could also try to disable the firmware upload at si2168 and see
> if the si2157 reads will succeed.

That too. Thanks for the advice.
Gon Solo Oct. 3, 2019, 6:32 p.m. UTC | #30
> You could also try to disable the firmware upload at si2168 and see
> if the si2157 reads will succeed.

I disabled the upload and while vlc wasn't working anymore I got the
following messages:

[  168.196656] si2157 2-0063: found a 'Silicon Labs Si2147-A30'
[  168.223009] si2157 2-0063: firmware version: 3.0.5


It really seems that the firmware upload is the culprit.

g
Jan Pieter van Woerkom Oct. 3, 2019, 6:42 p.m. UTC | #31
On 10/3/19 8:32 PM, Gon Solo wrote:
>> You could also try to disable the firmware upload at si2168 and see
>> if the si2157 reads will succeed.
> I disabled the upload and while vlc wasn't working anymore I got the
> following messages:
>
> [  168.196656] si2157 2-0063: found a 'Silicon Labs Si2147-A30'
> [  168.223009] si2157 2-0063: firmware version: 3.0.5
>
>
> It really seems that the firmware upload is the culprit.

try other firmware?
http://palosaari.fi/linux/v4l-dvb/firmware/Si2168/
>
> g
>
>
Gon Solo Oct. 3, 2019, 6:50 p.m. UTC | #32
> try other firmware?
> http://palosaari.fi/linux/v4l-dvb/firmware/Si2168/

I already downloaded version 4.0.25 from there.

-rw-r--r-- 1 root    root    6,8K Apr  5  2018
/lib/firmware/dvb-demod-si2168-b40-01.fw.gonzo
-rw-rw-r-- 1 gonsolo gonsolo  16K Okt  3 13:08
/lib/firmware/dvb-demod-si2168-b40-01.fw

No difference.
Gon Solo Oct. 3, 2019, 6:53 p.m. UTC | #33
I also tried to add a msleep(1000) after the si2168 firmware upload;
no difference.

g
Gon Solo Oct. 3, 2019, 7:19 p.m. UTC | #34
> try other firmware?
> http://palosaari.fi/linux/v4l-dvb/firmware/Si2168/

I tried all of them. No difference.
Mauro Carvalho Chehab Oct. 3, 2019, 7:39 p.m. UTC | #35
Em Thu, 3 Oct 2019 21:19:16 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> > try other firmware?
> > http://palosaari.fi/linux/v4l-dvb/firmware/Si2168/  
> 
> I tried all of them. No difference.

Maybe the vendor of this device wrote a different firmware. That happens.

Thanks,
Mauro
Gon Solo Oct. 3, 2019, 7:40 p.m. UTC | #36
From si2168.c:808:
               /* Sometimes firmware returns bogus value */
                if (utmp1 == 0xffff)
                        utmp1 = 0;

Maybe we can include my "bogus" hack to get at least Logilink running.
Maybe with an info message to tell users what is going on.

g
Mauro Carvalho Chehab Oct. 3, 2019, 7:44 p.m. UTC | #37
Em Thu, 3 Oct 2019 16:39:14 -0300
Mauro Carvalho Chehab <mchehab+samsung@kernel.org> escreveu:

> Em Thu, 3 Oct 2019 21:19:16 +0200
> Gonsolo <gonsolo@gmail.com> escreveu:
> 
> > > try other firmware?
> > > http://palosaari.fi/linux/v4l-dvb/firmware/Si2168/    
> > 
> > I tried all of them. No difference.  
> 
> Maybe the vendor of this device wrote a different firmware. That happens.

Two additional comments:

1) The firmware file is likely at the Windows driver for this device
(probably using a different format). It should be possible to get
it from there. 

2) Another possibility would be to add a way to tell the si2168 driver
to not try to load a firmware, using the original one. That would
require adding a field at si2168_config to allow signalizing to it
that it should not try to load a firmware file, and add a quirk at
the af9035 that would set such flag for Logilink VG0022A.

Option (1) is the best one.

Thanks,
Mauro
Gon Solo Oct. 3, 2019, 7:51 p.m. UTC | #38
> 1) The firmware file is likely at the Windows driver for this device
> (probably using a different format). It should be possible to get
> it from there.

If you tell me how I'm willing to do this. :)

> 2) Another possibility would be to add a way to tell the si2168 driver
> to not try to load a firmware, using the original one. That would
> require adding a field at si2168_config to allow signalizing to it
> that it should not try to load a firmware file, and add a quirk at
> the af9035 that would set such flag for Logilink VG0022A.

I don't get this. Which firmware, si2168 or si2157?

I'm still for option 3: If there is a bogus chip revision number it's
likely the VG0022A and we can safely set fw to NULL, in which case
everything works.
All already working devices will continue to work as before.
With a low probability there are other devices that will return 0xffff
but a) they didn't work until now and b) they receive a clear message
that they return bogus numbers and this works just for the VG0022A, in
which case this hardware can be tested.
At last, *my* VG0022A will work without a custom kernel which I'm a
big fan of. :))

Are there any counterarguments except that it is not the cleanest
solution in the universe? ;)
Mauro Carvalho Chehab Oct. 3, 2019, 7:52 p.m. UTC | #39
Em Thu, 3 Oct 2019 21:40:28 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> From si2168.c:808:
>                /* Sometimes firmware returns bogus value */
>                 if (utmp1 == 0xffff)
>                         utmp1 = 0;

Huh? are you using the upstream Kernel? the above code is at line 215!

Please always use the upstream code when sending patches.

> 
> Maybe we can include my "bogus" hack to get at least Logilink running.
> Maybe with an info message to tell users what is going on.
> 
> g



Thanks,
Mauro
Gon Solo Oct. 3, 2019, 7:57 p.m. UTC | #40
> Huh? are you using the upstream Kernel? the above code is at line 215!
> Please always use the upstream code when sending patches.

Sorry, I was confused by my vi line:
"drivers/media/dvb-frontends/si2168.c" 808 lines --26%--
                                         212,1-8       25%"

Twelve hours behind this screen. I think I have to have a walk in the
forest right now. :)
Mauro Carvalho Chehab Oct. 3, 2019, 8:03 p.m. UTC | #41
Em Thu, 3 Oct 2019 21:51:35 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> > 1) The firmware file is likely at the Windows driver for this device
> > (probably using a different format). It should be possible to get
> > it from there.  
> 
> If you tell me how I'm willing to do this. :)

I don't know. I was not the one that extracted the firmware. I guess
Antti did it.

I suspect that there are some comments about that in the past at the
ML. seek at lore.kernel.org.

> 
> > 2) Another possibility would be to add a way to tell the si2168 driver
> > to not try to load a firmware, using the original one. That would
> > require adding a field at si2168_config to allow signalizing to it
> > that it should not try to load a firmware file, and add a quirk at
> > the af9035 that would set such flag for Logilink VG0022A.  
> 
> I don't get this. Which firmware, si2168 or si2157?

The one that it is causing the problem. If I understood well, the
culprit was the si2168 firmware.

> I'm still for option 3: If there is a bogus chip revision number it's
> likely the VG0022A and we can safely set fw to NULL, in which case
> everything works.
> All already working devices will continue to work as before.
> With a low probability there are other devices that will return 0xffff
> but a) they didn't work until now and b) they receive a clear message
> that they return bogus numbers and this works just for the VG0022A, in
> which case this hardware can be tested.
> At last, *my* VG0022A will work without a custom kernel which I'm a
> big fan of. :))
> 
> Are there any counterarguments except that it is not the cleanest
> solution in the universe? ;)

That's a really bad solution. Returning 0xff is what happens when
things go wrong during I2C transfers. Several problems can cause it,
including device misfunction. Every time someone comes with a patch
trying to ignore it, things go sideways for other devices (existing
or future ones).

Ignoring errors is always a bad idea.

Also, it is a very bad idea to load a firmware that it is not
compatible with a device. There are even cases of devices that
were burned due to that[1].

[1] XCeive has two versions of 3028/2028 chipsets. One with a
"normal power" and a "low power" version. If the firmware for
the "normal power" (version 2.7) is used at the "low power" chip
(with requires version 3.6), it makes the chipset hotter and
reduces a lot the lifetime of the tuner.

Thanks,
Mauro
Gon Solo Oct. 3, 2019, 8:32 p.m. UTC | #42
> I don't know. I was not the one that extracted the firmware. I guess
> Antti did it.

Ok.

> That's a really bad solution. Returning 0xff is what happens when
> things go wrong during I2C transfers. Several problems can cause it,
> including device misfunction. Every time someone comes with a patch
> trying to ignore it, things go sideways for other devices (existing
> or future ones).
>
> Ignoring errors is always a bad idea.

I understand.

Anyway, I have to give up for now. Maybe I will have some time in the
future to come back to this or somebody else can use the information
in this thread. :(

Thanks for your time, I appreciate that very much. It was worth a try. :)
Jan Pieter van Woerkom Oct. 4, 2019, 11:50 a.m. UTC | #43
On 10/3/19 10:03 PM, Mauro Carvalho Chehab wrote:
> Em Thu, 3 Oct 2019 21:51:35 +0200
> Gonsolo <gonsolo@gmail.com> escreveu:
>
>>> 1) The firmware file is likely at the Windows driver for this device
>>> (probably using a different format). It should be possible to get
>>> it from there.
>> If you tell me how I'm willing to do this. :)
> I don't know. I was not the one that extracted the firmware. I guess
> Antti did it.
>
> I suspect that there are some comments about that in the past at the
> ML. seek at lore.kernel.org.
>
>>> 2) Another possibility would be to add a way to tell the si2168 driver
>>> to not try to load a firmware, using the original one. That would
>>> require adding a field at si2168_config to allow signalizing to it
>>> that it should not try to load a firmware file, and add a quirk at
>>> the af9035 that would set such flag for Logilink VG0022A.
>> I don't get this. Which firmware, si2168 or si2157?
> The one that it is causing the problem. If I understood well, the
> culprit was the si2168 firmware.
>
>> I'm still for option 3: If there is a bogus chip revision number it's
>> likely the VG0022A and we can safely set fw to NULL, in which case
>> everything works.
>> All already working devices will continue to work as before.
>> With a low probability there are other devices that will return 0xffff
>> but a) they didn't work until now and b) they receive a clear message
>> that they return bogus numbers and this works just for the VG0022A, in
>> which case this hardware can be tested.
>> At last, *my* VG0022A will work without a custom kernel which I'm a
>> big fan of. :))
>>
>> Are there any counterarguments except that it is not the cleanest
>> solution in the universe? ;)
> That's a really bad solution. Returning 0xff is what happens when
> things go wrong during I2C transfers. Several problems can cause it,
> including device misfunction. Every time someone comes with a patch
> trying to ignore it, things go sideways for other devices (existing
> or future ones).
>
> Ignoring errors is always a bad idea.
add module param say 'gonso_hack_vg0022a'
if true, act on error by setting a flag
if this flag is set don't load firmware

Jan Pieter.
Mauro Carvalho Chehab Oct. 4, 2019, 12:08 p.m. UTC | #44
Em Fri, 4 Oct 2019 13:50:43 +0200
JP <jp@jpvw.nl> escreveu:

> On 10/3/19 10:03 PM, Mauro Carvalho Chehab wrote:
> > Em Thu, 3 Oct 2019 21:51:35 +0200
> > Gonsolo <gonsolo@gmail.com> escreveu:
> >  
> >>> 1) The firmware file is likely at the Windows driver for this device
> >>> (probably using a different format). It should be possible to get
> >>> it from there.  
> >> If you tell me how I'm willing to do this. :)  
> > I don't know. I was not the one that extracted the firmware. I guess
> > Antti did it.
> >
> > I suspect that there are some comments about that in the past at the
> > ML. seek at lore.kernel.org.
> >  
> >>> 2) Another possibility would be to add a way to tell the si2168 driver
> >>> to not try to load a firmware, using the original one. That would
> >>> require adding a field at si2168_config to allow signalizing to it
> >>> that it should not try to load a firmware file, and add a quirk at
> >>> the af9035 that would set such flag for Logilink VG0022A.  
> >> I don't get this. Which firmware, si2168 or si2157?  
> > The one that it is causing the problem. If I understood well, the
> > culprit was the si2168 firmware.
> >  
> >> I'm still for option 3: If there is a bogus chip revision number it's
> >> likely the VG0022A and we can safely set fw to NULL, in which case
> >> everything works.
> >> All already working devices will continue to work as before.
> >> With a low probability there are other devices that will return 0xffff
> >> but a) they didn't work until now and b) they receive a clear message
> >> that they return bogus numbers and this works just for the VG0022A, in
> >> which case this hardware can be tested.
> >> At last, *my* VG0022A will work without a custom kernel which I'm a
> >> big fan of. :))
> >>
> >> Are there any counterarguments except that it is not the cleanest
> >> solution in the universe? ;)  
> > That's a really bad solution. Returning 0xff is what happens when
> > things go wrong during I2C transfers. Several problems can cause it,
> > including device misfunction. Every time someone comes with a patch
> > trying to ignore it, things go sideways for other devices (existing
> > or future ones).
> >
> > Ignoring errors is always a bad idea.  
> add module param say 'gonso_hack_vg0022a'
> if true, act on error by setting a flag
> if this flag is set don't load firmware

Adding a module param should be the last resort, only when there's
no way for the driver to autodetect.

Making af9035 to detect vg0022a is quite simple.

Considering this device's entry:

	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
		&it930x_props, "Logilink VG0022A", NULL) },

the check, at af9035 would be:

	if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK &&
	    le16_to_cpu(d->udev->descriptor.idProduct) == 0x0100)
		/* do something to disable firmware load */

So, no need to add any load time parameter.

It should be noticed that a change just at af9035 won't work, as the
firmware is updated by si2168 driver. So, the caller code needs to
pass a config parameter to si2168 driver.

Thanks,
Mauro
Jan Pieter van Woerkom Oct. 4, 2019, 1:50 p.m. UTC | #45
On 10/4/19 2:08 PM, Mauro Carvalho Chehab wrote:
> Em Fri, 4 Oct 2019 13:50:43 +0200
> JP <jp@jpvw.nl> escreveu:
>
>> On 10/3/19 10:03 PM, Mauro Carvalho Chehab wrote:
>>> Em Thu, 3 Oct 2019 21:51:35 +0200
>>> Gonsolo <gonsolo@gmail.com> escreveu:
>>>   
>>>>> 1) The firmware file is likely at the Windows driver for this device
>>>>> (probably using a different format). It should be possible to get
>>>>> it from there.
>>>> If you tell me how I'm willing to do this. :)
>>> I don't know. I was not the one that extracted the firmware. I guess
>>> Antti did it.
>>>
>>> I suspect that there are some comments about that in the past at the
>>> ML. seek at lore.kernel.org.
>>>   
>>>>> 2) Another possibility would be to add a way to tell the si2168 driver
>>>>> to not try to load a firmware, using the original one. That would
>>>>> require adding a field at si2168_config to allow signalizing to it
>>>>> that it should not try to load a firmware file, and add a quirk at
>>>>> the af9035 that would set such flag for Logilink VG0022A.
>>>> I don't get this. Which firmware, si2168 or si2157?
>>> The one that it is causing the problem. If I understood well, the
>>> culprit was the si2168 firmware.
>>>   
>>>> I'm still for option 3: If there is a bogus chip revision number it's
>>>> likely the VG0022A and we can safely set fw to NULL, in which case
>>>> everything works.
>>>> All already working devices will continue to work as before.
>>>> With a low probability there are other devices that will return 0xffff
>>>> but a) they didn't work until now and b) they receive a clear message
>>>> that they return bogus numbers and this works just for the VG0022A, in
>>>> which case this hardware can be tested.
>>>> At last, *my* VG0022A will work without a custom kernel which I'm a
>>>> big fan of. :))
>>>>
>>>> Are there any counterarguments except that it is not the cleanest
>>>> solution in the universe? ;)
>>> That's a really bad solution. Returning 0xff is what happens when
>>> things go wrong during I2C transfers. Several problems can cause it,
>>> including device misfunction. Every time someone comes with a patch
>>> trying to ignore it, things go sideways for other devices (existing
>>> or future ones).
>>>
>>> Ignoring errors is always a bad idea.
>> add module param say 'gonso_hack_vg0022a'
>> if true, act on error by setting a flag
>> if this flag is set don't load firmware
> Adding a module param should be the last resort, only when there's
> no way for the driver to autodetect.
Remember the guy reported the hw fix? Could be that
only some receiver units are affected. Therefore  the
module param.

The hw fix was original 4k7 and 10k added. That looks
like 3k3 total and all 3 chips on the bus work. 10k per
chip. Now Gon reported that said bus works with 2 chips
active on a faulty device with 4k7 resistor, which is 2
times 10k. It looks same hw error to me.
> Making af9035 to detect vg0022a is quite simple.
>
> Considering this device's entry:
>
> 	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
> 		&it930x_props, "Logilink VG0022A", NULL) },
>
> the check, at af9035 would be:
>
> 	if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK &&
> 	    le16_to_cpu(d->udev->descriptor.idProduct) == 0x0100)
> 		/* do something to disable firmware load */
>
> So, no need to add any load time parameter.
>
> It should be noticed that a change just at af9035 won't work, as the
> firmware is updated by si2168 driver. So, the caller code needs to
> pass a config parameter to si2168 driver.
If it is a failing pull-up resistor on only some individual receiver
units, this seems overkill to me. In my proposal I did not realized
this change in the demod driver was needed.

> Thanks,
> Mauro
>
Thank you.
Mauro Carvalho Chehab Oct. 4, 2019, 2:16 p.m. UTC | #46
Em Fri, 4 Oct 2019 15:50:18 +0200
JP <jp@jpvw.nl> escreveu:

> On 10/4/19 2:08 PM, Mauro Carvalho Chehab wrote:
> > Em Fri, 4 Oct 2019 13:50:43 +0200
> > JP <jp@jpvw.nl> escreveu:
> >  
> >> On 10/3/19 10:03 PM, Mauro Carvalho Chehab wrote:  
> >>> Em Thu, 3 Oct 2019 21:51:35 +0200
> >>> Gonsolo <gonsolo@gmail.com> escreveu:
> >>>     
> >>>>> 1) The firmware file is likely at the Windows driver for this device
> >>>>> (probably using a different format). It should be possible to get
> >>>>> it from there.  
> >>>> If you tell me how I'm willing to do this. :)  
> >>> I don't know. I was not the one that extracted the firmware. I guess
> >>> Antti did it.
> >>>
> >>> I suspect that there are some comments about that in the past at the
> >>> ML. seek at lore.kernel.org.
> >>>     
> >>>>> 2) Another possibility would be to add a way to tell the si2168 driver
> >>>>> to not try to load a firmware, using the original one. That would
> >>>>> require adding a field at si2168_config to allow signalizing to it
> >>>>> that it should not try to load a firmware file, and add a quirk at
> >>>>> the af9035 that would set such flag for Logilink VG0022A.  
> >>>> I don't get this. Which firmware, si2168 or si2157?  
> >>> The one that it is causing the problem. If I understood well, the
> >>> culprit was the si2168 firmware.
> >>>     
> >>>> I'm still for option 3: If there is a bogus chip revision number it's
> >>>> likely the VG0022A and we can safely set fw to NULL, in which case
> >>>> everything works.
> >>>> All already working devices will continue to work as before.
> >>>> With a low probability there are other devices that will return 0xffff
> >>>> but a) they didn't work until now and b) they receive a clear message
> >>>> that they return bogus numbers and this works just for the VG0022A, in
> >>>> which case this hardware can be tested.
> >>>> At last, *my* VG0022A will work without a custom kernel which I'm a
> >>>> big fan of. :))
> >>>>
> >>>> Are there any counterarguments except that it is not the cleanest
> >>>> solution in the universe? ;)  
> >>> That's a really bad solution. Returning 0xff is what happens when
> >>> things go wrong during I2C transfers. Several problems can cause it,
> >>> including device misfunction. Every time someone comes with a patch
> >>> trying to ignore it, things go sideways for other devices (existing
> >>> or future ones).
> >>>
> >>> Ignoring errors is always a bad idea.  
> >> add module param say 'gonso_hack_vg0022a'
> >> if true, act on error by setting a flag
> >> if this flag is set don't load firmware  
> > Adding a module param should be the last resort, only when there's
> > no way for the driver to autodetect.  
> Remember the guy reported the hw fix? Could be that
> only some receiver units are affected. Therefore  the
> module param.
> 
> The hw fix was original 4k7 and 10k added. That looks
> like 3k3 total and all 3 chips on the bus work. 10k per
> chip. Now Gon reported that said bus works with 2 chips
> active on a faulty device with 4k7 resistor, which is 2
> times 10k. It looks same hw error to me.

I'm not so sure. From the reports from Gonsolo, in the case of 
this specific issue with VG0022A, the device is not unstable. It is 
just that it works fine with the vendor-provided firmware, while it 
breaks with the new one.

We don't know that the same thing would happen with the original
reported bug. The only way to be sure would be to obtain the same
hardware from the original post and test it to check if the device
has issues without replacing the resistor.

Even the original reporter can't help, as his device was modified,
and the issue won't be there anymore.

Btw, if we end by noticing this bug happening on other it931x
device models, we could simply disable firmware load for all of them,
but we need more tests and reports before changing the behavior for
other models, as older firmwares may have other problems.

> > Making af9035 to detect vg0022a is quite simple.
> >
> > Considering this device's entry:
> >
> > 	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
> > 		&it930x_props, "Logilink VG0022A", NULL) },
> >
> > the check, at af9035 would be:
> >
> > 	if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK &&
> > 	    le16_to_cpu(d->udev->descriptor.idProduct) == 0x0100)
> > 		/* do something to disable firmware load */
> >
> > So, no need to add any load time parameter.
> >
> > It should be noticed that a change just at af9035 won't work, as the
> > firmware is updated by si2168 driver. So, the caller code needs to
> > pass a config parameter to si2168 driver.  

> If it is a failing pull-up resistor on only some individual receiver
> units, this seems overkill to me. In my proposal I did not realized
> this change in the demod driver was needed.

Agreed, but we have no means to know that until someone buys other
units of the VG0022A and do tests with and without the patch.

Thanks,
Mauro
diff mbox series

Patch

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index e87040d6eca7..8f9df2485d51 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -66,6 +66,24 @@  static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd)
 	return ret;
 }
 
+static int si2157_power_up(struct si2157_dev *dev, struct i2c_client *client)
+{
+	struct si2157_cmd cmd;
+
+	if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
+		memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
+		cmd.wlen = 9;
+	} else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+		memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
+		cmd.wlen = 10;
+	} else {
+		memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
+		cmd.wlen = 15;
+	}
+	cmd.rlen = 1;
+	return si2157_cmd_execute(client, &cmd);
+}
+
 static int si2157_init(struct dvb_frontend *fe)
 {
 	struct i2c_client *client = fe->tuner_priv;
@@ -75,7 +93,7 @@  static int si2157_init(struct dvb_frontend *fe)
 	struct si2157_cmd cmd;
 	const struct firmware *fw;
 	const char *fw_name;
-	unsigned int uitmp, chip_id;
+	unsigned int uitmp;
 
 	dev_dbg(&client->dev, "\n");
 
@@ -93,19 +111,7 @@  static int si2157_init(struct dvb_frontend *fe)
 	if (uitmp == dev->if_frequency / 1000)
 		goto warm;
 
-	/* power up */
-	if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
-		memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
-		cmd.wlen = 9;
-	} else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
-		memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
-		cmd.wlen = 10;
-	} else {
-		memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
-		cmd.wlen = 15;
-	}
-	cmd.rlen = 1;
-	ret = si2157_cmd_execute(client, &cmd);
+	ret = si2157_power_up(dev, client);
 	if (ret)
 		goto err;
 
@@ -118,17 +124,6 @@  static int si2157_init(struct dvb_frontend *fe)
 			goto err;
 	}
 
-	/* query chip revision */
-	memcpy(cmd.args, "\x02", 1);
-	cmd.wlen = 1;
-	cmd.rlen = 13;
-	ret = si2157_cmd_execute(client, &cmd);
-	if (ret)
-		goto err;
-
-	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
-			cmd.args[4] << 0;
-
 	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
 	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
 	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
@@ -137,7 +132,7 @@  static int si2157_init(struct dvb_frontend *fe)
 	#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
 	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
 
-	switch (chip_id) {
+	switch (dev->chip_id) {
 	case SI2158_A20:
 	case SI2148_A20:
 		fw_name = SI2158_A20_FIRMWARE;
@@ -456,6 +451,27 @@  static int si2157_probe(struct i2c_client *client,
 	memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops));
 	fe->tuner_priv = client;
 
+	ret = si2157_power_up(dev, client);
+	if (ret)
+		goto err;
+	/* query chip revision */
+	/* hack: do it here because after the si2168 gets 0101, commands will
+	 * still be executed here but no result
+	 */
+	memcpy(cmd.args, "\x02", 1);
+	cmd.wlen = 1;
+	cmd.rlen = 13;
+	ret = si2157_cmd_execute(client, &cmd);
+	if (ret)
+		goto err_kfree;
+	dev->chip_id = cmd.args[1] << 24 |
+		cmd.args[2] << 16 |
+		cmd.args[3] << 8 |
+		cmd.args[4] << 0;
+	dev_info(&client->dev, "found a 'Silicon Labs Si21%d-%c%c%c'\n",
+		cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
+
+
 #ifdef CONFIG_MEDIA_CONTROLLER
 	if (cfg->mdev) {
 		dev->mdev = cfg->mdev;
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index 2bda903358da..9ab7c88b01b4 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -28,6 +28,7 @@  struct si2157_dev {
 	u8 chiptype;
 	u8 if_port;
 	u32 if_frequency;
+	u32 chip_id;
 	struct delayed_work stat_work;
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 3afd18733614..83e243df59b9 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -1246,6 +1246,51 @@  static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
 
 	msleep(200);
 
+	if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK) {
+
+		ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01);
+		if (ret < 0)
+			goto err;
+
+		/* I2C master bus 2 clock speed 300k */
+		ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
+		if (ret < 0)
+			goto err;
+
+		/* I2C master bus 1,3 clock speed 300k */
+		ret = af9035_wr_reg(d, 0x00f103, 0x07);
+		if (ret < 0)
+			goto err;
+
+		/* set gpio11 low */
+		ret = af9035_wr_reg_mask(d, 0xd8d4, 0x01, 0x01);
+		if (ret < 0)
+			goto err;
+
+		ret = af9035_wr_reg_mask(d, 0xd8d5, 0x01, 0x01);
+		if (ret < 0)
+			goto err;
+
+		ret = af9035_wr_reg_mask(d, 0xd8d3, 0x01, 0x01);
+		if (ret < 0)
+			goto err;
+
+		/* Tuner enable using gpiot2_en, gpiot2_on and gpiot2_o (reset) */
+		ret = af9035_wr_reg_mask(d, 0xd8b8, 0x01, 0x01);
+		if (ret < 0)
+			goto err;
+
+		ret = af9035_wr_reg_mask(d, 0xd8b9, 0x01, 0x01);
+		if (ret < 0)
+			goto err;
+
+		ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01);
+		if (ret < 0)
+			goto err;
+
+		msleep(200);
+	}
+
 	ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01);
 	if (ret < 0)
 		goto err;
@@ -2119,6 +2164,8 @@  static const struct usb_device_id af9035_id_table[] = {
 	/* IT930x devices */
 	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
 		&it930x_props, "ITE 9303 Generic", NULL) },
+	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
+		&it930x_props, "Logilink VG0022A", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310,
 		&it930x_props, "AVerMedia TD310 DVB-T2", NULL) },
 	{ }