[1/3,media] si2157: get chip id during probing

Message ID 1489616530-4025-2-git-send-email-andreas@kemnade.info (mailing list archive)
State Changes Requested, archived
Headers

Commit Message

Andreas Kemnade March 15, 2017, 10:22 p.m. UTC
  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

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 drivers/media/tuners/si2157.c      | 54 ++++++++++++++++++++++----------------
 drivers/media/tuners/si2157_priv.h |  7 +++++
 2 files changed, 39 insertions(+), 22 deletions(-)
  

Comments

Antti Palosaari April 23, 2017, 12:19 p.m. UTC | #1
On 03/16/2017 12:22 AM, Andreas Kemnade wrote:
> 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
That is hackish solution :( Somehow I2C reads should be get working 
rather than making this kind of work-around. Returning 0xff to i2c reads 
means that signal strength also shows some wrong static value?

regards
Antti
  
Andreas Kemnade April 23, 2017, 12:38 p.m. UTC | #2
On Sun, 23 Apr 2017 15:19:21 +0300
Antti Palosaari <crope@iki.fi> wrote:

> On 03/16/2017 12:22 AM, Andreas Kemnade wrote:
> > 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
> That is hackish solution :( Somehow I2C reads should be get working 
> rather than making this kind of work-around. Returning 0xff to i2c reads 
> means that signal strength also shows some wrong static value?
> 
dvb-fe-tool -m is like this:

Lock   (0x1f) Signal= -1.00dBm C/N= 19.25dB UCB= 6061140 postBER= 40.0x10^-6

Signal strength is static.

Yes, I do not like my solution, too.
Also i2c reads from the windows driver from the si2157 after that 0101
command give such problems. I have checked my usb logs again.
So the question is where a better solution can come from.
I do not find a proper datasheet of the si2157 or the si2168.

Just for reference: the stick is labeled VG0022a.
The usb strings are like that:
  idVendor           0x1d19 Dexatek Technology Ltd.
  idProduct          0x0100 
  bcdDevice            1.00
  iManufacturer           1 ITE Tech., Inc.
  iProduct                2 TS Aggregator
  iSerial                 3 AF0102020700001

if that may lead to some information.

Regards,
Andreas
  
Andreas Kemnade May 15, 2017, 8:28 p.m. UTC | #3
Hi,

On Sun, 23 Apr 2017 15:19:21 +0300
Antti Palosaari <crope@iki.fi> wrote:

> On 03/16/2017 12:22 AM, Andreas Kemnade wrote:
> > 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
> That is hackish solution :( Somehow I2C reads should be get working 
> rather than making this kind of work-around. Returning 0xff to i2c reads 
> means that signal strength also shows some wrong static value?
> 
Also this is needed for the Terratec CinergyTC2.
I see the ff even on windows. So it cannot be solved by usb-sniffing of
a working system, so, again how should we proceed?

a) not support dvb sticks which do not work with your preferred
   order of initialization.

b) change order of initialisation (maybe optionally add a flag like
   INIT_TUNER_BEFORE_DEMOD to avoid risk of breaking other things)

c) something like the current patch.

d) while(!i2c_readable(tuner)) {
     write_random_data_to_demod();
     write_random_data_it9306_bridge();
   }
   remember_random_data();


There was not much feedback here.

An excerpt from my windows sniff logs:
ep: 02 l:   15 GEN_I2C_WR 00 0603c6120100000000
ep: 02 l:    0
ep: 81 l:    0
ep: 81 l:    5 042300dcff
ep: 02 l:    9 GEN_I2C_RD 00 0603c6
ep: 02 l:    0
ep: 81 l:    0
ep: 81 l:   11 0a240080ffffffffff5b02
ep: 02 l:   15 GEN_I2C_WR 00 0603c6140011070300
ep: 02 l:    0
ep: 81 l:    0
ep: 81 l:    5 042500daff
ep: 02 l:    9 GEN_I2C_RD 00 0403c6
ep: 02 l:    0
ep: 81 l:    0
ep: 81 l:    9 08260080ffffff5901

here you see all the ffff from the device.



Regards,
Andreas
  
Antti Palosaari May 24, 2017, 8:55 a.m. UTC | #4
On 05/15/2017 11:28 PM, Andreas Kemnade wrote:
> Hi,
> 
> On Sun, 23 Apr 2017 15:19:21 +0300
> Antti Palosaari <crope@iki.fi> wrote:
> 
>> On 03/16/2017 12:22 AM, Andreas Kemnade wrote:
>>> 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
>> That is hackish solution :( Somehow I2C reads should be get working
>> rather than making this kind of work-around. Returning 0xff to i2c reads
>> means that signal strength also shows some wrong static value?
>>
> Also this is needed for the Terratec CinergyTC2.
> I see the ff even on windows. So it cannot be solved by usb-sniffing of
> a working system, so, again how should we proceed?
> 
> a) not support dvb sticks which do not work with your preferred
>     order of initialization.
> 
> b) change order of initialisation (maybe optionally add a flag like
>     INIT_TUNER_BEFORE_DEMOD to avoid risk of breaking other things)
> 
> c) something like the current patch.
> 
> d) while(!i2c_readable(tuner)) {
>       write_random_data_to_demod();
>       write_random_data_it9306_bridge();
>     }
>     remember_random_data();
> 
> 
> There was not much feedback here.

If it is not possible to fix i2c communication then better to add some 
device specific logic to i2c adapter in order to meet demod/tuner 
requirements.


> 
> An excerpt from my windows sniff logs:
> ep: 02 l:   15 GEN_I2C_WR 00 0603c6120100000000
> ep: 02 l:    0
> ep: 81 l:    0
> ep: 81 l:    5 042300dcff
> ep: 02 l:    9 GEN_I2C_RD 00 0603c6
> ep: 02 l:    0
> ep: 81 l:    0
> ep: 81 l:   11 0a240080ffffffffff5b02
> ep: 02 l:   15 GEN_I2C_WR 00 0603c6140011070300
> ep: 02 l:    0
> ep: 81 l:    0
> ep: 81 l:    5 042500daff
> ep: 02 l:    9 GEN_I2C_RD 00 0403c6
> ep: 02 l:    0
> ep: 81 l:    0
> ep: 81 l:    9 08260080ffffff5901
> 
> here you see all the ffff from the device.
> 
> 
> 
> Regards,
> Andreas
> 

regards
Antti
  
Steven Toth May 26, 2017, 2:32 p.m. UTC | #5
>> ep: 81 l:    9 08260080ffffff5901
>>
>> here you see all the ffff from the device.

You need to be able to see the traffic on the physical I2C bus in
order to help diagnose issues like this. You're going to want to see
ACKS/NAKS, clocks and other I2C bus activity.

You'll need to solder down scl/sda/gnd wiring to the PCB, I generally
attached to the eeprom which tends to have larger pins (details on
their respective datasheets).

It's not hard to do, but does require a small investment in hardware.

One the actual bus behavior is documented and understood, you'll
likely get a better technical discussion going on.

Send me a detailed picture of the PCB and I can probably help spot the
I2C bus for you, if you have a low cost bus analyzer and a soldering
iron.
  

Patch

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 57b2508..0da7a33 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");
 
@@ -115,24 +115,7 @@  static int si2157_init(struct dvb_frontend *fe)
 	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 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)
-
-	switch (chip_id) {
+	switch (dev->chip_id) {
 	case SI2158_A20:
 	case SI2148_A20:
 		fw_name = SI2158_A20_FIRMWARE;
@@ -150,9 +133,6 @@  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]);
-
 	if (fw_name == NULL)
 		goto skip_fw_download;
 
@@ -444,6 +424,36 @@  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) {
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index d6b2c7b..54c1a856 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -30,6 +30,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,12 @@  struct si2157_dev {
 #define SI2157_CHIPTYPE_SI2157 0
 #define SI2157_CHIPTYPE_SI2146 1
 
+#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)
+
 /* firmware command struct */
 #define SI2157_ARGLEN      30
 struct si2157_cmd {