diff mbox series

DVB-T2 Stick

Message ID CANL0fFSGG_+R2zbf-9MxVLJMTMgc+-fwSoLCqS1qc+jWo-zNLA@mail.gmail.com (mailing list archive)
State New, archived
Headers show
Series DVB-T2 Stick | expand

Commit Message

Gon Solo Jan. 30, 2019, 10:32 a.m. UTC
Hi!

The following patch adds support for the Logilink VG0022A DVB-T2 stick.
After patching and building the kernel it shows up with lsusb and I
used w_scan to scan for channels and vlc for watching.
The original patches were from Andreas Kemnade.
The only thing that doesn't work is wake up after standby.

Do you think you can apply this patch?

Thanks

Comments

Sean Young Feb. 19, 2019, 9:30 p.m. UTC | #1
Hi,

On Wed, Jan 30, 2019 at 11:32:12AM +0100, Gonsolo wrote:
> Hi!
> 
> The following patch adds support for the Logilink VG0022A DVB-T2 stick.
> After patching and building the kernel it shows up with lsusb and I
> used w_scan to scan for channels and vlc for watching.
> The original patches were from Andreas Kemnade.
> The only thing that doesn't work is wake up after standby.
> 
> Do you think you can apply this patch?

I'm afraid there are many problems with this patch. First of all it looks
like support was added for a si2168 tuner but it looks like it will break
for any other si2157-type device.

Secondly there are lots of coding style issues, see:

https://www.kernel.org/doc/html/v4.10/process/coding-style.html

Thanks,

Sean
> 
> Thanks
> -- 
> g

> diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
> index d389f1fc237a..1f923418ff10 100644
> --- a/drivers/media/tuners/si2157.c
> +++ b/drivers/media/tuners/si2157.c
> @@ -84,7 +84,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");
>  
> @@ -126,7 +126,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  		if (ret)
>  			goto err;
>  	}
> -
> +#if 0
>  	/* query chip revision */
>  	memcpy(cmd.args, "\x02", 1);
>  	cmd.wlen = 1;
> @@ -146,6 +146,8 @@ static int si2157_init(struct dvb_frontend *fe)
>  	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
>  
>  	switch (chip_id) {
> +#endif
> +        switch (dev->chip_id) {
>  	case SI2158_A20:
>  	case SI2148_A20:
>  		fw_name = SI2158_A20_FIRMWARE;
> @@ -166,9 +168,9 @@ static int si2157_init(struct dvb_frontend *fe)
>  		goto err;
>  	}
>  
> -	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]);
> -
> +//	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]);
> +//
>  	if (fw_name == NULL)
>  		goto skip_fw_download;
>  
> @@ -461,6 +463,38 @@ static int si2157_probe(struct i2c_client *client,
>  	memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops));
>  	fe->tuner_priv = client;
>  
> +       /* 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 {
> +               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);
> +       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 50f86300d965..3592146cf49a 100644
> --- a/drivers/media/tuners/si2157_priv.h
> +++ b/drivers/media/tuners/si2157_priv.h
> @@ -37,6 +37,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)
> @@ -51,6 +52,13 @@ struct si2157_dev {
>  #define SI2157_CHIPTYPE_SI2146 1
>  #define SI2157_CHIPTYPE_SI2141 2
>  
> +#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)
> +
>  /* firmware command struct */
>  #define SI2157_ARGLEN      30
>  struct si2157_cmd {
> diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
> index 80d3bd3a0f24..28b073bfe0d4 100644
> --- a/drivers/media/usb/dvb-usb-v2/af9035.c
> +++ b/drivers/media/usb/dvb-usb-v2/af9035.c
> @@ -1216,8 +1216,51 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
>  	struct si2168_config si2168_config;
>  	struct i2c_adapter *adapter;
>  
> -	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
> -
> +	//dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
> +       dev_dbg(&intf->dev, "%s  adap->id=%d\n", __func__, adap->id);
> +
> +       /* 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;
> + 
>  	memset(&si2168_config, 0, sizeof(si2168_config));
>  	si2168_config.i2c_adapter = &adapter;
>  	si2168_config.fe = &adap->fe[0];
> @@ -2128,6 +2171,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) },
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(usb, af9035_id_table);
Gon Solo Oct. 1, 2019, 10:19 p.m. UTC | #2
Hi!

> Secondly there are lots of coding style issues, see:
> https://www.kernel.org/doc/html/v4.10/process/coding-style.html

I addressed most of these except one "#if 0" warning from checkpatch.

> I'm afraid there are many problems with this patch. First of all it looks
> like support was added for a si2168 tuner but it looks like it will break
> for any other si2157-type device.


Can you give me a hint how to proceed here? I don't know much about
DVB tuners or kernel development.

I attached the cleaned-up patch for 5.4.0-rc1

Thanks,
g
Mauro Carvalho Chehab Oct. 1, 2019, 11:52 p.m. UTC | #3
Em Wed, 2 Oct 2019 00:19:05 +0200
Gonsolo <gonsolo@gmail.com> escreveu:

> Hi!
> 
> > Secondly there are lots of coding style issues, see:
> > https://www.kernel.org/doc/html/v4.10/process/coding-style.html
> 
> I addressed most of these except one "#if 0" warning from checkpatch.
> 
> > I'm afraid there are many problems with this patch. First of all it looks
> > like support was added for a si2168 tuner but it looks like it will break
> > for any other si2157-type device.
> 
> 
> Can you give me a hint how to proceed here? I don't know much about
> DVB tuners or kernel development.
> 
> I attached the cleaned-up patch for 5.4.0-rc1

First of all, don't attach a patch. Instead, just send it with a decent
emailer (with won't mangle whitespaces) or use git send-email...

Also, please read the Developer's section of our wiki page:

	https://linuxtv.org/wiki/index.php/Developer_section

In special, the "Submitting your work" part of it.

> 
> Thanks,
> g
> From 6cada6442207a67202e73721692aced665b8fdf0 Mon Sep 17 00:00:00 2001
> From: Gon Solo <gonsolo@gmail.com>
> Date: Tue, 1 Oct 2019 21:59:44 +0200
> Subject: [PATCH] DVB-T2 with coding style updates.
> 
> ---
>  drivers/media/tuners/si2157.c         | 44 ++++++++++++++++++++++---
>  drivers/media/tuners/si2157_priv.h    |  8 +++++
>  drivers/media/usb/dvb-usb-v2/af9035.c | 47 ++++++++++++++++++++++++++-
>  3 files changed, 93 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
> index e87040d6eca7..af50e721281b 100644
> --- a/drivers/media/tuners/si2157.c
> +++ b/drivers/media/tuners/si2157.c
> @@ -75,7 +75,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");
>  
> @@ -117,7 +117,7 @@ static int si2157_init(struct dvb_frontend *fe)
>  		if (ret)
>  			goto err;
>  	}
> -
> +#if 0
>  	/* query chip revision */
>  	memcpy(cmd.args, "\x02", 1);
>  	cmd.wlen = 1;
> @@ -138,6 +138,8 @@ static int si2157_init(struct dvb_frontend *fe)
>  	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
>  
>  	switch (chip_id) {
> +#endif
> +	switch (dev->chip_id) {

You shouldn't just blindly comment out some code, as this will very likely 
break support for all other devices supported by the driver...

>  	case SI2158_A20:
>  	case SI2148_A20:
>  		fw_name = SI2158_A20_FIRMWARE;
> @@ -161,9 +163,9 @@ static int si2157_init(struct dvb_frontend *fe)
>  		goto err;
>  	}
>  
> -	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]);
> -
> +//	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]);
> +//
>  	if (fw_name == NULL)
>  		goto skip_fw_download;
>  
> @@ -456,6 +458,38 @@ static int si2157_probe(struct i2c_client *client,
>  	memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops));
>  	fe->tuner_priv = client;
>  
> +	/* 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 {
> +		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);
> +	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]);
> +
> +

... yet, looking on what you've done, it seems that you're actually
adding support for a different tuner at the si2157 driver.

If this is the case, this should be on a separate patch, and in a way
that it will become clear that it won't break support for any existing
device.

Also, please remove the dead code, instead of commenting it out.

>  #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..0f4090e184e9 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)
> @@ -43,6 +44,13 @@ struct si2157_dev {
>  #define SI2157_CHIPTYPE_SI2141 2
>  #define SI2157_CHIPTYPE_SI2177 3
>  
> +#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)
> +
>  /* firmware command struct */
>  #define SI2157_ARGLEN      30
>  struct si2157_cmd {
> diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
> index 3afd18733614..5b7a00cdcbd8 100644
> --- a/drivers/media/usb/dvb-usb-v2/af9035.c
> +++ b/drivers/media/usb/dvb-usb-v2/af9035.c
> @@ -1206,7 +1206,50 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
>  	struct si2168_config si2168_config;
>  	struct i2c_adapter *adapter;
>  
> -	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
> +	//dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
> +	dev_dbg(&intf->dev, "%s  adap->id=%d\n", __func__, adap->id);

Why did you do such change? dev_dbg can already print the function, and
much more. See:

	https://lwn.net/Articles/434833/

> +
> +	/* 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;

The above seems specific for your device. You need to check if the device
is USB_VID_DEXATEK, running the code only on such case.

>  
>  	/* I2C master bus 2 clock speed 300k */
>  	ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
> @@ -2118,6 +2161,8 @@ static const struct usb_device_id af9035_id_table[] = {
>  
>  	/* IT930x devices */
>  	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
> +	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100,
> +		&it930x_props, "Logilink VG0022A", NULL) },
>  		&it930x_props, "ITE 9303 Generic", NULL) },
>  	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310,
>  		&it930x_props, "AVerMedia TD310 DVB-T2", NULL) },


Thanks,
Mauro
Gon Solo Oct. 2, 2019, 2:13 p.m. UTC | #4
Dear Mauro!

Thanks for your reply, I tried to address most of your concerns,
so please bear with me (especially this is my first email with
git send-email). :)

> First of all, don't attach a patch. Instead, just send it with a decent
> emailer (with won't mangle whitespaces) or use git send-email...

Done.

> You shouldn't just blindly comment out some code, as this will very likely
> break support for all other devices supported by the driver...

Done. I extracted power_up into its own function, chip querying is now
done in probe. I don't have enough knowledge about hardware to do the
right thing on my own. If there is anybody willing to guide me I will
spend some time on it.

The original patch where the problem is discussed is
https://lkml.kernel.org/lkml/1489616530-4025-1-git-send-email-andreas@kemnade.info

> ... yet, looking on what you've done, it seems that you're actually
> adding support for a different tuner at the si2157 driver.
> If this is the case, this should be on a separate patch, and in a way
> that it will become clear that it won't break support for any existing
> device.

I'm not entirely sure how to split this up. Can you give some advice?

> Why did you do such change? dev_dbg can already print the function, and
> much more. See:

Thanks for the link. I removed these lines.

> The above seems specific for your device. You need to check if the device
> is USB_VID_DEXATEK, running the code only on such case.

Done. Though I'm not sure whether I did it the right way.

Thanks for all the advice, I hope this will be included eventually.
g
diff mbox series

Patch

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index d389f1fc237a..1f923418ff10 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -84,7 +84,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");
 
@@ -126,7 +126,7 @@  static int si2157_init(struct dvb_frontend *fe)
 		if (ret)
 			goto err;
 	}
-
+#if 0
 	/* query chip revision */
 	memcpy(cmd.args, "\x02", 1);
 	cmd.wlen = 1;
@@ -146,6 +146,8 @@  static int si2157_init(struct dvb_frontend *fe)
 	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
 
 	switch (chip_id) {
+#endif
+        switch (dev->chip_id) {
 	case SI2158_A20:
 	case SI2148_A20:
 		fw_name = SI2158_A20_FIRMWARE;
@@ -166,9 +168,9 @@  static int si2157_init(struct dvb_frontend *fe)
 		goto err;
 	}
 
-	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]);
-
+//	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]);
+//
 	if (fw_name == NULL)
 		goto skip_fw_download;
 
@@ -461,6 +463,38 @@  static int si2157_probe(struct i2c_client *client,
 	memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops));
 	fe->tuner_priv = client;
 
+       /* 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 {
+               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);
+       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 50f86300d965..3592146cf49a 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -37,6 +37,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)
@@ -51,6 +52,13 @@  struct si2157_dev {
 #define SI2157_CHIPTYPE_SI2146 1
 #define SI2157_CHIPTYPE_SI2141 2
 
+#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)
+
 /* firmware command struct */
 #define SI2157_ARGLEN      30
 struct si2157_cmd {
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 80d3bd3a0f24..28b073bfe0d4 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -1216,8 +1216,51 @@  static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
 	struct si2168_config si2168_config;
 	struct i2c_adapter *adapter;
 
-	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
-
+	//dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
+       dev_dbg(&intf->dev, "%s  adap->id=%d\n", __func__, adap->id);
+
+       /* 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;
+ 
 	memset(&si2168_config, 0, sizeof(si2168_config));
 	si2168_config.i2c_adapter = &adapter;
 	si2168_config.fe = &adap->fe[0];
@@ -2128,6 +2171,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) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, af9035_id_table);