linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/18] si2157: implement sleep
@ 2014-07-14 17:08 Antti Palosaari
  2014-07-14 17:08 ` [PATCH 02/18] si2168: " Antti Palosaari
                   ` (16 more replies)
  0 siblings, 17 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Implement sleep for power-management.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/tuners/si2157.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index fa4cc7b..082e80e 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -89,12 +89,23 @@ static int si2157_init(struct dvb_frontend *fe)
 static int si2157_sleep(struct dvb_frontend *fe)
 {
 	struct si2157 *s = fe->tuner_priv;
+	int ret;
+	struct si2157_cmd cmd;
 
 	dev_dbg(&s->client->dev, "%s:\n", __func__);
 
 	s->active = false;
 
+	memcpy(cmd.args, "\x13", 1);
+	cmd.len = 1;
+	ret = si2157_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
 	return 0;
+err:
+	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
 }
 
 static int si2157_set_params(struct dvb_frontend *fe)
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/18] si2168: implement sleep
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 03/18] si2168: set cmd args using memcpy Antti Palosaari
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Implement sleep for power-management.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 2e3cdcf..13cf2a8 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -438,13 +438,6 @@ static int si2168_init(struct dvb_frontend *fe)
 
 	dev_dbg(&s->client->dev, "%s:\n", __func__);
 
-	cmd.args[0] = 0x13;
-	cmd.wlen = 1;
-	cmd.rlen = 0;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	cmd.args[0] = 0xc0;
 	cmd.args[1] = 0x12;
 	cmd.args[2] = 0x00;
@@ -545,12 +538,24 @@ err:
 static int si2168_sleep(struct dvb_frontend *fe)
 {
 	struct si2168 *s = fe->demodulator_priv;
+	int ret;
+	struct si2168_cmd cmd;
 
 	dev_dbg(&s->client->dev, "%s:\n", __func__);
 
 	s->active = false;
 
+	memcpy(cmd.args, "\x13", 1);
+	cmd.wlen = 1;
+	cmd.rlen = 0;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
 	return 0;
+err:
+	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
 }
 
 static int si2168_get_tune_settings(struct dvb_frontend *fe,
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/18] si2168: set cmd args using memcpy
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
  2014-07-14 17:08 ` [PATCH 02/18] si2168: " Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 04/18] si2168: implement CNR statistic Antti Palosaari
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Use memcpy for set cmd buffer in order to keep style in line with
rest of file.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c | 39 ++++++++----------------------------
 1 file changed, 8 insertions(+), 31 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 13cf2a8..78af598 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -95,20 +95,17 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
 
 	switch (c->delivery_system) {
 	case SYS_DVBT:
-		cmd.args[0] = 0xa0;
-		cmd.args[1] = 0x01;
+		memcpy(cmd.args, "\xa0\x01", 2);
 		cmd.wlen = 2;
 		cmd.rlen = 13;
 		break;
 	case SYS_DVBC_ANNEX_A:
-		cmd.args[0] = 0x90;
-		cmd.args[1] = 0x01;
+		memcpy(cmd.args, "\x90\x01", 2);
 		cmd.wlen = 2;
 		cmd.rlen = 9;
 		break;
 	case SYS_DVBT2:
-		cmd.args[0] = 0x50;
-		cmd.args[1] = 0x01;
+		memcpy(cmd.args, "\x50\x01", 2);
 		cmd.wlen = 2;
 		cmd.rlen = 14;
 		break;
@@ -412,7 +409,7 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	cmd.args[0] = 0x85;
+	memcpy(cmd.args, "\x85", 1);
 	cmd.wlen = 1;
 	cmd.rlen = 1;
 	ret = si2168_cmd_execute(s, &cmd);
@@ -438,40 +435,21 @@ static int si2168_init(struct dvb_frontend *fe)
 
 	dev_dbg(&s->client->dev, "%s:\n", __func__);
 
-	cmd.args[0] = 0xc0;
-	cmd.args[1] = 0x12;
-	cmd.args[2] = 0x00;
-	cmd.args[3] = 0x0c;
-	cmd.args[4] = 0x00;
-	cmd.args[5] = 0x0d;
-	cmd.args[6] = 0x16;
-	cmd.args[7] = 0x00;
-	cmd.args[8] = 0x00;
-	cmd.args[9] = 0x00;
-	cmd.args[10] = 0x00;
-	cmd.args[11] = 0x00;
-	cmd.args[12] = 0x00;
+	memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
 	cmd.wlen = 13;
 	cmd.rlen = 0;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
-	cmd.args[0] = 0xc0;
-	cmd.args[1] = 0x06;
-	cmd.args[2] = 0x01;
-	cmd.args[3] = 0x0f;
-	cmd.args[4] = 0x00;
-	cmd.args[5] = 0x20;
-	cmd.args[6] = 0x20;
-	cmd.args[7] = 0x01;
+	memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
 	cmd.wlen = 8;
 	cmd.rlen = 1;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
-	cmd.args[0] = 0x02;
+	memcpy(cmd.args, "\x02", 1);
 	cmd.wlen = 1;
 	cmd.rlen = 13;
 	ret = si2168_cmd_execute(s, &cmd);
@@ -513,8 +491,7 @@ static int si2168_init(struct dvb_frontend *fe)
 	release_firmware(fw);
 	fw = NULL;
 
-	cmd.args[0] = 0x01;
-	cmd.args[1] = 0x01;
+	memcpy(cmd.args, "\x01\x01", 2);
 	cmd.wlen = 2;
 	cmd.rlen = 1;
 	ret = si2168_cmd_execute(s, &cmd);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/18] si2168: implement CNR statistic
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
  2014-07-14 17:08 ` [PATCH 02/18] si2168: " Antti Palosaari
  2014-07-14 17:08 ` [PATCH 03/18] si2168: set cmd args using memcpy Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 05/18] si2157: add read data support for fw cmd func Antti Palosaari
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Implement CNR statistic.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 78af598..bfd7525 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -141,6 +141,15 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
 
 	s->fe_status = *status;
 
+	if (*status & FE_HAS_LOCK) {
+		c->cnr.len = 1;
+		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+		c->cnr.stat[0].svalue = cmd.args[3] * 1000 / 4;
+	} else {
+		c->cnr.len = 1;
+		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	}
+
 	dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
 			__func__, *status, cmd.rlen, cmd.args);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/18] si2157: add read data support for fw cmd func
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (2 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 04/18] si2168: implement CNR statistic Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 06/18] si2168: remove duplicate command Antti Palosaari
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

We want also read data from firmware. Add support for it. Copied from
si2168 driver.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/tuners/si2157.c      | 74 +++++++++++++++++++++-----------------
 drivers/media/tuners/si2157_priv.h |  3 +-
 2 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 082e80e..a4908ee 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -20,50 +20,52 @@
 static int si2157_cmd_execute(struct si2157 *s, struct si2157_cmd *cmd)
 {
 	int ret;
-	u8 buf[1];
 	unsigned long timeout;
 
 	mutex_lock(&s->i2c_mutex);
 
-	if (cmd->len) {
+	if (cmd->wlen) {
 		/* write cmd and args for firmware */
-		ret = i2c_master_send(s->client, cmd->args, cmd->len);
+		ret = i2c_master_send(s->client, cmd->args, cmd->wlen);
 		if (ret < 0) {
 			goto err_mutex_unlock;
-		} else if (ret != cmd->len) {
+		} else if (ret != cmd->wlen) {
 			ret = -EREMOTEIO;
 			goto err_mutex_unlock;
 		}
 	}
 
-	/* wait cmd execution terminate */
-	#define TIMEOUT 80
-	timeout = jiffies + msecs_to_jiffies(TIMEOUT);
-	while (!time_after(jiffies, timeout)) {
-		ret = i2c_master_recv(s->client, buf, 1);
-		if (ret < 0) {
-			goto err_mutex_unlock;
-		} else if (ret != 1) {
-			ret = -EREMOTEIO;
-			goto err_mutex_unlock;
+	if (cmd->rlen) {
+		/* wait cmd execution terminate */
+		#define TIMEOUT 80
+		timeout = jiffies + msecs_to_jiffies(TIMEOUT);
+		while (!time_after(jiffies, timeout)) {
+			ret = i2c_master_recv(s->client, cmd->args, cmd->rlen);
+			if (ret < 0) {
+				goto err_mutex_unlock;
+			} else if (ret != cmd->rlen) {
+				ret = -EREMOTEIO;
+				goto err_mutex_unlock;
+			}
+
+			/* firmware ready? */
+			if ((cmd->args[0] >> 7) & 0x01)
+				break;
 		}
 
-		/* firmware ready? */
-		if ((buf[0] >> 7) & 0x01)
-			break;
-	}
+		dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n",
+				__func__,
+				jiffies_to_msecs(jiffies) -
+				(jiffies_to_msecs(timeout) - TIMEOUT));
 
-	dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n", __func__,
-			jiffies_to_msecs(jiffies) -
-			(jiffies_to_msecs(timeout) - TIMEOUT));
-
-	if (!((buf[0] >> 7) & 0x01)) {
-		ret = -ETIMEDOUT;
-		goto err_mutex_unlock;
-	} else {
-		ret = 0;
+		if (!((cmd->args[0] >> 7) & 0x01)) {
+			ret = -ETIMEDOUT;
+			goto err_mutex_unlock;
+		}
 	}
 
+	ret = 0;
+
 err_mutex_unlock:
 	mutex_unlock(&s->i2c_mutex);
 	if (ret)
@@ -97,7 +99,8 @@ static int si2157_sleep(struct dvb_frontend *fe)
 	s->active = false;
 
 	memcpy(cmd.args, "\x13", 1);
-	cmd.len = 1;
+	cmd.wlen = 1;
+	cmd.rlen = 0;
 	ret = si2157_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
@@ -141,20 +144,23 @@ static int si2157_set_params(struct dvb_frontend *fe)
 	cmd.args[12] = 0x00;
 	cmd.args[13] = 0x00;
 	cmd.args[14] = 0x01;
-	cmd.len = 15;
+	cmd.wlen = 15;
+	cmd.rlen = 1;
 	ret = si2157_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	cmd.args[0] = 0x02;
-	cmd.len = 1;
+	cmd.wlen = 1;
+	cmd.rlen = 13;
 	ret = si2157_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	cmd.args[0] = 0x01;
 	cmd.args[1] = 0x01;
-	cmd.len = 2;
+	cmd.wlen = 2;
+	cmd.rlen = 1;
 	ret = si2157_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
@@ -168,7 +174,8 @@ static int si2157_set_params(struct dvb_frontend *fe)
 	cmd.args[5] = (c->frequency >>  8) & 0xff;
 	cmd.args[6] = (c->frequency >> 16) & 0xff;
 	cmd.args[7] = (c->frequency >> 24) & 0xff;
-	cmd.len = 8;
+	cmd.wlen = 8;
+	cmd.rlen = 1;
 	ret = si2157_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
@@ -212,7 +219,8 @@ static int si2157_probe(struct i2c_client *client,
 	mutex_init(&s->i2c_mutex);
 
 	/* check if the tuner is there */
-	cmd.len = 0;
+	cmd.wlen = 0;
+	cmd.rlen = 1;
 	ret = si2157_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index 6cc6c6f..6db4c97 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -31,7 +31,8 @@ struct si2157 {
 #define SI2157_ARGLEN      30
 struct si2157_cmd {
 	u8 args[SI2157_ARGLEN];
-	unsigned len;
+	unsigned wlen;
+	unsigned rlen;
 };
 
 #endif
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/18] si2168: remove duplicate command
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (3 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 05/18] si2157: add read data support for fw cmd func Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 07/18] si2168: do not set values which are already on default Antti Palosaari
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Same command was executed twice, but different value. Remove
redundant command.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index bfd7525..432703c 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -334,7 +334,7 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x01\x10\x00\x00", 6);
+	memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
 	cmd.wlen = 6;
 	cmd.rlen = 1;
 	ret = si2168_cmd_execute(s, &cmd);
@@ -404,13 +404,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
 	cmd.wlen = 6;
 	cmd.rlen = 1;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/18] si2168: do not set values which are already on default
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (4 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 06/18] si2168: remove duplicate command Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 08/18] si2168: receive 4 bytes reply from cmd 0x14 Antti Palosaari
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

No need to set explicitly value that are already defaulted same.

Setting new value returns old value. Firmware default values can
be found just looking returned value.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c | 98 ------------------------------------
 1 file changed, 98 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 432703c..666d428 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -249,27 +249,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x01\x04\x00\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x03\x10\x17\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x02\x10\x15\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
 	cmd.wlen = 6;
 	cmd.rlen = 1;
@@ -284,13 +263,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x0b\x10\x88\x13", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
 	cmd.wlen = 6;
 	cmd.rlen = 1;
@@ -306,20 +278,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x04\x10\x15\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x05\x10\xa1\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
 	cmd.wlen = 6;
 	cmd.rlen = 1;
@@ -327,13 +285,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x0d\x10\xd0\x02", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
 	cmd.wlen = 6;
 	cmd.rlen = 1;
@@ -355,55 +306,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x04\x03\x00\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x03\x03\x00\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x08\x03\x00\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x07\x03\x01\x02", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x06\x03\x00\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x05\x03\x00\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x40", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 1;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
 	cmd.wlen = 6;
 	cmd.rlen = 1;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/18] si2168: receive 4 bytes reply from cmd 0x14
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (5 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 07/18] si2168: do not set values which are already on default Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 09/18] si2168: Small typo fix (SI2157 -> SI2168) Antti Palosaari
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Command 0x14 returns 4 bytes as a reply. It is used for setting
key/value pairs to firmware and it returns 4 bytes back including
old value.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 666d428..bae7771 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -251,21 +251,21 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 
 	memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
@@ -273,42 +273,42 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
 	cmd.args[4] = delivery_system | bandwidth;
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6);
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
 
 	memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
 	cmd.wlen = 6;
-	cmd.rlen = 1;
+	cmd.rlen = 4;
 	ret = si2168_cmd_execute(s, &cmd);
 	if (ret)
 		goto err;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/18] si2168: Small typo fix (SI2157 -> SI2168)
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (6 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 08/18] si2168: receive 4 bytes reply from cmd 0x14 Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 10/18] si2168: Add support for chip revision Si2168 A30 Antti Palosaari
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

From: Olli Salonen <olli.salonen@iki.fi>

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Reviewed-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/si2168_priv.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
index 53f7f06..97f9d87 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -36,9 +36,9 @@ struct si2168 {
 };
 
 /* firmare command struct */
-#define SI2157_ARGLEN      30
+#define SI2168_ARGLEN      30
 struct si2168_cmd {
-	u8 args[SI2157_ARGLEN];
+	u8 args[SI2168_ARGLEN];
 	unsigned wlen;
 	unsigned rlen;
 };
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/18] si2168: Add support for chip revision Si2168 A30
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (7 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 09/18] si2168: Small typo fix (SI2157 -> SI2168) Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 11/18] si2157: Move chip initialization to si2157_init Antti Palosaari
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

From: Olli Salonen <olli.salonen@iki.fi>

Add handling for different chip revisions and firmwares.

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Reviewed-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c      | 34 ++++++++++++++++++++++++++-----
 drivers/media/dvb-frontends/si2168_priv.h |  4 +++-
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index bae7771..268fce3 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -333,7 +333,7 @@ static int si2168_init(struct dvb_frontend *fe)
 	struct si2168 *s = fe->demodulator_priv;
 	int ret, len, remaining;
 	const struct firmware *fw = NULL;
-	u8 *fw_file = SI2168_FIRMWARE;
+	u8 *fw_file;
 	const unsigned int i2c_wr_max = 8;
 	struct si2168_cmd cmd;
 
@@ -353,6 +353,7 @@ static int si2168_init(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
+	/* query chip revision */
 	memcpy(cmd.args, "\x02", 1);
 	cmd.wlen = 1;
 	cmd.rlen = 13;
@@ -360,6 +361,20 @@ static int si2168_init(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
+	if (((cmd.args[1] & 0x0f) == 2) && (cmd.args[3] == '4') &&
+			(cmd.args[4] == '0'))
+		fw_file = SI2168_B40_FIRMWARE;
+	else if (((cmd.args[1] & 0x0f) == 1) && (cmd.args[3] == '3') &&
+			(cmd.args[4] == '0'))
+		fw_file = SI2168_A30_FIRMWARE;
+	else {
+		dev_err(&s->client->dev,
+				"%s: no firmware file for Si2168-%c%c defined\n",
+				KBUILD_MODNAME, cmd.args[3], cmd.args[4]);
+		ret = -EINVAL;
+		goto err;
+	}
+
 	/* cold state - try to download firmware */
 	dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
 			KBUILD_MODNAME, si2168_ops.info.name);
@@ -367,9 +382,18 @@ static int si2168_init(struct dvb_frontend *fe)
 	/* request the firmware, this will block and timeout */
 	ret = request_firmware(&fw, fw_file, &s->client->dev);
 	if (ret) {
-		dev_err(&s->client->dev, "%s: firmare file '%s' not found\n",
-				KBUILD_MODNAME, fw_file);
-		goto err;
+		/* fallback mechanism to handle old name for
+		   SI2168_B40_FIRMWARE */
+		if (((cmd.args[1] & 0x0f) == 2) && (cmd.args[3] == '4') &&
+				(cmd.args[4] == '0')) {
+			fw_file = SI2168_B40_FIRMWARE_FALLBACK;
+			ret = request_firmware(&fw, fw_file, &s->client->dev);
+		}
+		if (ret) {
+			dev_err(&s->client->dev, "%s: firmware file '%s' not found\n",
+					KBUILD_MODNAME, fw_file);
+			goto err;
+		}
 	}
 
 	dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
@@ -629,4 +653,4 @@ module_i2c_driver(si2168_driver);
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
 MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(SI2168_FIRMWARE);
+MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
index 97f9d87..bebb68a 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -22,7 +22,9 @@
 #include <linux/firmware.h>
 #include <linux/i2c-mux.h>
 
-#define SI2168_FIRMWARE "dvb-demod-si2168-02.fw"
+#define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
+#define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw"
+#define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
 
 /* state struct */
 struct si2168 {
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 11/18] si2157: Move chip initialization to si2157_init
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (8 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 10/18] si2168: Add support for chip revision Si2168 A30 Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 12/18] si2157: Add support for Si2158 chip Antti Palosaari
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

From: Olli Salonen <olli.salonen@iki.fi>

Move chip initialization related code from si2157_set_params to
si2157_init.

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Reviewed-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/tuners/si2157.c | 71 ++++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 41 deletions(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index a4908ee..a92570f9 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -80,12 +80,41 @@ err:
 static int si2157_init(struct dvb_frontend *fe)
 {
 	struct si2157 *s = fe->tuner_priv;
+	int ret;
+	struct si2157_cmd cmd;
 
 	dev_dbg(&s->client->dev, "%s:\n", __func__);
 
+	/* configure? */
+	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(s, &cmd);
+	if (ret)
+		goto err;
+
+	/* query chip revision */
+	memcpy(cmd.args, "\x02", 1);
+	cmd.wlen = 1;
+	cmd.rlen = 13;
+	ret = si2157_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	/* reboot the tuner with new firmware? */
+	memcpy(cmd.args, "\x01\x01", 2);
+	cmd.wlen = 2;
+	cmd.rlen = 1;
+	ret = si2157_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
 	s->active = true;
 
 	return 0;
+err:
+	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
 }
 
 static int si2157_sleep(struct dvb_frontend *fe)
@@ -128,48 +157,8 @@ static int si2157_set_params(struct dvb_frontend *fe)
 		goto err;
 	}
 
-	/* configure? */
-	cmd.args[0] = 0xc0;
-	cmd.args[1] = 0x00;
-	cmd.args[2] = 0x0c;
-	cmd.args[3] = 0x00;
-	cmd.args[4] = 0x00;
-	cmd.args[5] = 0x01;
-	cmd.args[6] = 0x01;
-	cmd.args[7] = 0x01;
-	cmd.args[8] = 0x01;
-	cmd.args[9] = 0x01;
-	cmd.args[10] = 0x01;
-	cmd.args[11] = 0x02;
-	cmd.args[12] = 0x00;
-	cmd.args[13] = 0x00;
-	cmd.args[14] = 0x01;
-	cmd.wlen = 15;
-	cmd.rlen = 1;
-	ret = si2157_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	cmd.args[0] = 0x02;
-	cmd.wlen = 1;
-	cmd.rlen = 13;
-	ret = si2157_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
-	cmd.args[0] = 0x01;
-	cmd.args[1] = 0x01;
-	cmd.wlen = 2;
-	cmd.rlen = 1;
-	ret = si2157_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	/* set frequency */
-	cmd.args[0] = 0x41;
-	cmd.args[1] = 0x00;
-	cmd.args[2] = 0x00;
-	cmd.args[3] = 0x00;
+	memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8);
 	cmd.args[4] = (c->frequency >>  0) & 0xff;
 	cmd.args[5] = (c->frequency >>  8) & 0xff;
 	cmd.args[6] = (c->frequency >> 16) & 0xff;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 12/18] si2157: Add support for Si2158 chip
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (9 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 11/18] si2157: Move chip initialization to si2157_init Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 13/18] si2157: Set delivery system and bandwidth before tuning Antti Palosaari
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

From: Olli Salonen <olli.salonen@iki.fi>

Add support for Si2158 A20 chip.

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Reviewed-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/tuners/si2157.c      | 73 +++++++++++++++++++++++++++++++++++---
 drivers/media/tuners/si2157.h      |  2 +-
 drivers/media/tuners/si2157_priv.h |  5 ++-
 3 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index a92570f9..58c5ef5 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -1,5 +1,5 @@
 /*
- * Silicon Labs Si2157 silicon tuner driver
+ * Silicon Labs Si2157/2158 silicon tuner driver
  *
  * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
  *
@@ -16,6 +16,8 @@
 
 #include "si2157_priv.h"
 
+static const struct dvb_tuner_ops si2157_ops;
+
 /* execute firmware command */
 static int si2157_cmd_execute(struct si2157 *s, struct si2157_cmd *cmd)
 {
@@ -80,8 +82,11 @@ err:
 static int si2157_init(struct dvb_frontend *fe)
 {
 	struct si2157 *s = fe->tuner_priv;
-	int ret;
+	int ret, remaining;
 	struct si2157_cmd cmd;
+	u8 chip, len = 0;
+	const struct firmware *fw = NULL;
+	u8 *fw_file;
 
 	dev_dbg(&s->client->dev, "%s:\n", __func__);
 
@@ -101,6 +106,64 @@ static int si2157_init(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
+	chip = cmd.args[2]; /* 57 for Si2157, 58 for Si2158 */
+
+	/* Si2158 requires firmware download */
+	if (chip == 58) {
+		if (((cmd.args[1] & 0x0f) == 1) && (cmd.args[3] == '2') &&
+				(cmd.args[4] == '0'))
+			fw_file = SI2158_A20_FIRMWARE;
+		else {
+			dev_err(&s->client->dev,
+					"%s: no firmware file for Si%d-%c%c defined\n",
+					KBUILD_MODNAME, chip, cmd.args[3], cmd.args[4]);
+			ret = -EINVAL;
+			goto err;
+		}
+
+		/* cold state - try to download firmware */
+		dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
+				KBUILD_MODNAME, si2157_ops.info.name);
+
+		/* request the firmware, this will block and timeout */
+		ret = request_firmware(&fw, fw_file, &s->client->dev);
+		if (ret) {
+			dev_err(&s->client->dev, "%s: firmware file '%s' not found\n",
+					KBUILD_MODNAME, fw_file);
+			goto err;
+		}
+
+		dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
+				KBUILD_MODNAME, fw_file);
+
+		/* firmware should be n chunks of 17 bytes */
+		if (fw->size % 17 != 0) {
+			dev_err(&s->client->dev, "%s: firmware file '%s' is invalid\n",
+					KBUILD_MODNAME, fw_file);
+			ret = -EINVAL;
+			goto err;
+		}
+
+		for (remaining = fw->size; remaining > 0; remaining -= 17) {
+			memcpy(&len, &fw->data[fw->size - remaining], 1);
+			memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1],
+					len);
+			cmd.wlen = len;
+			cmd.rlen = 1;
+			ret = si2157_cmd_execute(s, &cmd);
+			if (ret) {
+				dev_err(&s->client->dev,
+						"%s: firmware download failed=%d\n",
+						KBUILD_MODNAME, ret);
+				goto err;
+			}
+		}
+
+		release_firmware(fw);
+		fw = NULL;
+
+	}
+
 	/* reboot the tuner with new firmware? */
 	memcpy(cmd.args, "\x01\x01", 2);
 	cmd.wlen = 2;
@@ -177,7 +240,7 @@ err:
 
 static const struct dvb_tuner_ops si2157_tuner_ops = {
 	.info = {
-		.name           = "Silicon Labs Si2157",
+		.name           = "Silicon Labs Si2157/Si2158",
 		.frequency_min  = 110000000,
 		.frequency_max  = 862000000,
 	},
@@ -221,7 +284,7 @@ static int si2157_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, s);
 
 	dev_info(&s->client->dev,
-			"%s: Silicon Labs Si2157 successfully attached\n",
+			"%s: Silicon Labs Si2157/Si2158 successfully attached\n",
 			KBUILD_MODNAME);
 	return 0;
 err:
@@ -263,6 +326,6 @@ static struct i2c_driver si2157_driver = {
 
 module_i2c_driver(si2157_driver);
 
-MODULE_DESCRIPTION("Silicon Labs Si2157 silicon tuner driver");
+MODULE_DESCRIPTION("Silicon Labs Si2157/Si2158 silicon tuner driver");
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h
index f469a09..4465c46 100644
--- a/drivers/media/tuners/si2157.h
+++ b/drivers/media/tuners/si2157.h
@@ -1,5 +1,5 @@
 /*
- * Silicon Labs Si2157 silicon tuner driver
+ * Silicon Labs Si2157/2158 silicon tuner driver
  *
  * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
  *
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index 6db4c97..db79f3c 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -1,5 +1,5 @@
 /*
- * Silicon Labs Si2157 silicon tuner driver
+ * Silicon Labs Si2157/2158 silicon tuner driver
  *
  * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
  *
@@ -17,6 +17,7 @@
 #ifndef SI2157_PRIV_H
 #define SI2157_PRIV_H
 
+#include <linux/firmware.h>
 #include "si2157.h"
 
 /* state struct */
@@ -35,4 +36,6 @@ struct si2157_cmd {
 	unsigned rlen;
 };
 
+#define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
+
 #endif
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 13/18] si2157: Set delivery system and bandwidth before tuning
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (10 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 12/18] si2157: Add support for Si2158 chip Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 14/18] cxusb: TechnoTrend CT2-4400 USB DVB-T2/C tuner support Antti Palosaari
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

From: Olli Salonen <olli.salonen@iki.fi>

Tell used TV standard and bandwidth for tuner firmware.

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Reviewed-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/tuners/si2157.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 58c5ef5..b656f9b 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -209,6 +209,7 @@ static int si2157_set_params(struct dvb_frontend *fe)
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int ret;
 	struct si2157_cmd cmd;
+	u8 bandwidth, delivery_system;
 
 	dev_dbg(&s->client->dev,
 			"%s: delivery_system=%d frequency=%u bandwidth_hz=%u\n",
@@ -220,6 +221,36 @@ static int si2157_set_params(struct dvb_frontend *fe)
 		goto err;
 	}
 
+	if (c->bandwidth_hz <= 6000000)
+		bandwidth = 0x06;
+	else if (c->bandwidth_hz <= 7000000)
+		bandwidth = 0x07;
+	else if (c->bandwidth_hz <= 8000000)
+		bandwidth = 0x08;
+	else
+		bandwidth = 0x0f;
+
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+	case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */
+			delivery_system = 0x20;
+			break;
+	case SYS_DVBC_ANNEX_A:
+			delivery_system = 0x30;
+			break;
+	default:
+			ret = -EINVAL;
+			goto err;
+	}
+
+	memcpy(cmd.args, "\x14\x00\x03\x07\x00\x00", 6);
+	cmd.args[4] = delivery_system | bandwidth;
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2157_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
 	/* set frequency */
 	memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8);
 	cmd.args[4] = (c->frequency >>  0) & 0xff;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 14/18] cxusb: TechnoTrend CT2-4400 USB DVB-T2/C tuner support
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (11 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 13/18] si2157: Set delivery system and bandwidth before tuning Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:19   ` Michael Ira Krufky
  2014-07-14 17:08 ` [PATCH 15/18] si2168: advertise Si2168 A30 firmware Antti Palosaari
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Michael Krufky, Antti Palosaari

From: Olli Salonen <olli.salonen@iki.fi>

USB ID 0b48:3014.

USB interface: Cypress CY7C68013A-56LTXC
Demodulator: Silicon Labs Si2168-30
Tuner: Silicon Labs Si2158-20

Cc: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Reviewed-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-core/dvb-usb-ids.h |   1 +
 drivers/media/usb/dvb-usb/Kconfig    |   3 +
 drivers/media/usb/dvb-usb/cxusb.c    | 191 ++++++++++++++++++++++++++++++++++-
 drivers/media/usb/dvb-usb/cxusb.h    |   2 +
 4 files changed, 196 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 11d2bea..f8e3150 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -244,6 +244,7 @@
 #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM	0x3009
 #define USB_PID_TECHNOTREND_CONNECT_CT3650		0x300d
+#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400		0x3014
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2	0x0081
 #define USB_PID_TERRATEC_CINERGY_HT_USB_XE		0x0058
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
index c5d9566..10aef21 100644
--- a/drivers/media/usb/dvb-usb/Kconfig
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -117,10 +117,12 @@ config DVB_USB_CXUSB
 	select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_ATBM8830 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_LGS8GXX if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MAX2165 if MEDIA_SUBDRV_AUTOSELECT
+	select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
 	help
 	  Say Y here to support the Conexant USB2.0 hybrid reference design.
 	  Currently, only DVB and ATSC modes are supported, analog mode
@@ -128,6 +130,7 @@ config DVB_USB_CXUSB
 
 	  Medion MD95700 hybrid USB2.0 device.
 	  DViCO FusionHDTV (Bluebird) USB2.0 devices
+	  TechnoTrend TVStick CT2-4400
 
 config DVB_USB_M920X
 	tristate "Uli m920x DVB-T USB2.0 support"
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index a1c641e..ad20c39 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -42,6 +42,8 @@
 #include "dib0070.h"
 #include "lgs8gxx.h"
 #include "atbm8830.h"
+#include "si2168.h"
+#include "si2157.h"
 
 /* Max transfer size done by I2C transfer functions */
 #define MAX_XFER_SIZE  64
@@ -144,6 +146,22 @@ static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
 	}
 }
 
+static int cxusb_tt_ct2_4400_gpio_tuner(struct dvb_usb_device *d, int onoff)
+{
+	u8 o[2], i;
+	int rc;
+
+	o[0] = 0x83;
+	o[1] = onoff;
+	rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
+
+	if (rc) {
+		deb_info("gpio_write failed.\n");
+		return -EIO;
+	}
+	return 0;
+}
+
 /* I2C */
 static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 			  int num)
@@ -505,6 +523,30 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
 	return 0;
 }
 
+static int cxusb_tt_ct2_4400_rc_query(struct dvb_usb_device *d)
+{
+	u8 i[2];
+	int ret;
+	u32 cmd, keycode;
+	u8 rc5_cmd, rc5_addr, rc5_toggle;
+
+	ret = cxusb_ctrl_msg(d, 0x10, NULL, 0, i, 2);
+	if (ret)
+		return ret;
+
+	cmd = (i[0] << 8) | i[1];
+
+	if (cmd != 0xffff) {
+		rc5_cmd = cmd & 0x3F; /* bits 1-6 for command */
+		rc5_addr = (cmd & 0x07C0) >> 6; /* bits 7-11 for address */
+		rc5_toggle = (cmd & 0x0800) >> 11; /* bit 12 for toggle */
+		keycode = (rc5_addr << 8) | rc5_cmd;
+		rc_keydown(d->rc_dev, keycode, rc5_toggle);
+	}
+
+	return 0;
+}
+
 static struct rc_map_table rc_map_dvico_mce_table[] = {
 	{ 0xfe02, KEY_TV },
 	{ 0xfe0e, KEY_MP3 },
@@ -1286,6 +1328,73 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
 	return 0;
 }
 
+static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap)
+{
+	struct dvb_usb_device *d = adap->dev;
+	struct cxusb_state *st = d->priv;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client_demod;
+	struct i2c_client *client_tuner;
+	struct i2c_board_info info;
+	struct si2168_config si2168_config;
+	struct si2157_config si2157_config;
+
+	/* reset the tuner */
+	if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) {
+		err("clear tuner gpio failed");
+		return -EIO;
+	}
+	msleep(100);
+	if (cxusb_tt_ct2_4400_gpio_tuner(d, 1) < 0) {
+		err("set tuner gpio failed");
+		return -EIO;
+	}
+	msleep(100);
+
+	/* attach frontend */
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.fe = &adap->fe_adap[0].fe;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+	info.addr = 0x64;
+	info.platform_data = &si2168_config;
+	request_module(info.type);
+	client_demod = i2c_new_device(&d->i2c_adap, &info);
+	if (client_demod == NULL || client_demod->dev.driver == NULL)
+		return -ENODEV;
+
+	if (!try_module_get(client_demod->dev.driver->owner)) {
+		i2c_unregister_device(client_demod);
+		return -ENODEV;
+	}
+
+	st->i2c_client_demod = client_demod;
+
+	/* attach tuner */
+	si2157_config.fe = adap->fe_adap[0].fe;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module(info.type);
+	client_tuner = i2c_new_device(adapter, &info);
+	if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
+		module_put(client_demod->dev.driver->owner);
+		i2c_unregister_device(client_demod);
+		return -ENODEV;
+	}
+	if (!try_module_get(client_tuner->dev.driver->owner)) {
+		i2c_unregister_device(client_tuner);
+		module_put(client_demod->dev.driver->owner);
+		i2c_unregister_device(client_demod);
+		return -ENODEV;
+	}
+
+	st->i2c_client_tuner = client_tuner;
+
+	return 0;
+}
+
 /*
  * DViCO has shipped two devices with the same USB ID, but only one of them
  * needs a firmware download.  Check the device class details to see if they
@@ -1367,6 +1476,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
 static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
 static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
 static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
+static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
@@ -1397,12 +1507,37 @@ static int cxusb_probe(struct usb_interface *intf,
 				     THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
 				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
 	    0)
 		return 0;
 
 	return -EINVAL;
 }
 
+static void cxusb_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	struct cxusb_state *st = d->priv;
+	struct i2c_client *client;
+
+	/* remove I2C client for tuner */
+	client = st->i2c_client_tuner;
+	if (client) {
+		module_put(client->dev.driver->owner);
+		i2c_unregister_device(client);
+	}
+
+	/* remove I2C client for demodulator */
+	client = st->i2c_client_demod;
+	if (client) {
+		module_put(client->dev.driver->owner);
+		i2c_unregister_device(client);
+	}
+
+	dvb_usb_device_exit(intf);
+}
+
 static struct usb_device_id cxusb_table [] = {
 	{ USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
 	{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
@@ -1424,6 +1559,7 @@ static struct usb_device_id cxusb_table [] = {
 	{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
 	{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
 	{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
+	{ USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) },
 	{}		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -2070,10 +2206,63 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
 	}
 };
 
+static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl         = CYPRESS_FX2,
+
+	.size_of_priv     = sizeof(struct cxusb_state),
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+		.num_frontends = 1,
+		.fe = {{
+			.streaming_ctrl   = cxusb_streaming_ctrl,
+			/* both frontend and tuner attached in the
+			   same function */
+			.frontend_attach  = cxusb_tt_ct2_4400_attach,
+
+			/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+				.count = 8,
+				.endpoint = 0x82,
+				.u = {
+					.bulk = {
+						.buffersize = 4096,
+					}
+				}
+			},
+		} },
+		},
+	},
+
+	.i2c_algo = &cxusb_i2c_algo,
+	.generic_bulk_ctrl_endpoint = 0x01,
+	.generic_bulk_ctrl_endpoint_response = 0x81,
+
+	.rc.core = {
+		.rc_codes       = RC_MAP_TT_1500,
+		.allowed_protos = RC_BIT_RC5,
+		.rc_query       = cxusb_tt_ct2_4400_rc_query,
+		.rc_interval    = 150,
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{
+			"TechnoTrend TVStick CT2-4400",
+			{ NULL },
+			{ &cxusb_table[20], NULL },
+		},
+	}
+};
+
 static struct usb_driver cxusb_driver = {
 	.name		= "dvb_usb_cxusb",
 	.probe		= cxusb_probe,
-	.disconnect     = dvb_usb_device_exit,
+	.disconnect     = cxusb_disconnect,
 	.id_table	= cxusb_table,
 };
 
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
index 1a51eaf..527ff79 100644
--- a/drivers/media/usb/dvb-usb/cxusb.h
+++ b/drivers/media/usb/dvb-usb/cxusb.h
@@ -30,6 +30,8 @@
 
 struct cxusb_state {
 	u8 gpio_write_state[3];
+	struct i2c_client *i2c_client_demod;
+	struct i2c_client *i2c_client_tuner;
 };
 
 #endif
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 15/18] si2168: advertise Si2168 A30 firmware
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (12 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 14/18] cxusb: TechnoTrend CT2-4400 USB DVB-T2/C tuner support Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 16/18] si2157: advertise Si2158 A20 firmware Antti Palosaari
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Driver uses that new firmware too, so advertise it.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Tested-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 268fce3..e9c138a 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -653,4 +653,5 @@ module_i2c_driver(si2168_driver);
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
 MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 16/18] si2157: advertise Si2158 A20 firmware
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (13 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 15/18] si2168: advertise Si2168 A30 firmware Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 17/18] si2168: few firmware download changes Antti Palosaari
  2014-07-14 17:08 ` [PATCH 18/18] si2157: rework firmware download logic a little bit Antti Palosaari
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Driver uses that firmware. Add it module firmware list.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Tested-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/tuners/si2157.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index b656f9b..3fa1f26 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -360,3 +360,4 @@ module_i2c_driver(si2157_driver);
 MODULE_DESCRIPTION("Silicon Labs Si2157/Si2158 silicon tuner driver");
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 17/18] si2168: few firmware download changes
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (14 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 16/18] si2157: advertise Si2158 A20 firmware Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  2014-07-14 17:08 ` [PATCH 18/18] si2157: rework firmware download logic a little bit Antti Palosaari
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Rework firmware selection logic a little bit.
Print notice asking user update firmware when old Si2168 B40
firmware is used.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Tested-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/dvb-frontends/si2168.c | 41 ++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index e9c138a..0422925 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -336,6 +336,7 @@ static int si2168_init(struct dvb_frontend *fe)
 	u8 *fw_file;
 	const unsigned int i2c_wr_max = 8;
 	struct si2168_cmd cmd;
+	unsigned int chip_id;
 
 	dev_dbg(&s->client->dev, "%s:\n", __func__);
 
@@ -361,16 +362,24 @@ static int si2168_init(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	if (((cmd.args[1] & 0x0f) == 2) && (cmd.args[3] == '4') &&
-			(cmd.args[4] == '0'))
-		fw_file = SI2168_B40_FIRMWARE;
-	else if (((cmd.args[1] & 0x0f) == 1) && (cmd.args[3] == '3') &&
-			(cmd.args[4] == '0'))
+	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
+			cmd.args[4] << 0;
+
+	#define SI2168_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
+	#define SI2168_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
+
+	switch (chip_id) {
+	case SI2168_A30:
 		fw_file = SI2168_A30_FIRMWARE;
-	else {
+		break;
+	case SI2168_B40:
+		fw_file = SI2168_B40_FIRMWARE;
+		break;
+	default:
 		dev_err(&s->client->dev,
-				"%s: no firmware file for Si2168-%c%c defined\n",
-				KBUILD_MODNAME, cmd.args[3], cmd.args[4]);
+				"%s: unkown chip version Si21%d-%c%c%c\n",
+				KBUILD_MODNAME, cmd.args[2], cmd.args[1],
+				cmd.args[3], cmd.args[4]);
 		ret = -EINVAL;
 		goto err;
 	}
@@ -382,15 +391,19 @@ static int si2168_init(struct dvb_frontend *fe)
 	/* request the firmware, this will block and timeout */
 	ret = request_firmware(&fw, fw_file, &s->client->dev);
 	if (ret) {
-		/* fallback mechanism to handle old name for
-		   SI2168_B40_FIRMWARE */
-		if (((cmd.args[1] & 0x0f) == 2) && (cmd.args[3] == '4') &&
-				(cmd.args[4] == '0')) {
+		/* fallback mechanism to handle old name for Si2168 B40 fw */
+		if (chip_id == SI2168_B40) {
 			fw_file = SI2168_B40_FIRMWARE_FALLBACK;
 			ret = request_firmware(&fw, fw_file, &s->client->dev);
 		}
-		if (ret) {
-			dev_err(&s->client->dev, "%s: firmware file '%s' not found\n",
+
+		if (ret == 0) {
+			dev_notice(&s->client->dev,
+					"%s: please install firmware file '%s'\n",
+					KBUILD_MODNAME, SI2168_B40_FIRMWARE);
+		} else {
+			dev_err(&s->client->dev,
+					"%s: firmware file '%s' not found\n",
 					KBUILD_MODNAME, fw_file);
 			goto err;
 		}
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 18/18] si2157: rework firmware download logic a little bit
  2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
                   ` (15 preceding siblings ...)
  2014-07-14 17:08 ` [PATCH 17/18] si2168: few firmware download changes Antti Palosaari
@ 2014-07-14 17:08 ` Antti Palosaari
  16 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:08 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen, Antti Palosaari

Rework firmware selection / chip detection logic a little bit.
Add missing release_firmware() to error path.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Tested-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/tuners/si2157.c | 108 +++++++++++++++++++++++-------------------
 1 file changed, 58 insertions(+), 50 deletions(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 3fa1f26..329004f 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -82,11 +82,11 @@ err:
 static int si2157_init(struct dvb_frontend *fe)
 {
 	struct si2157 *s = fe->tuner_priv;
-	int ret, remaining;
+	int ret, len, remaining;
 	struct si2157_cmd cmd;
-	u8 chip, len = 0;
 	const struct firmware *fw = NULL;
 	u8 *fw_file;
+	unsigned int chip_id;
 
 	dev_dbg(&s->client->dev, "%s:\n", __func__);
 
@@ -106,64 +106,69 @@ static int si2157_init(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	chip = cmd.args[2]; /* 57 for Si2157, 58 for Si2158 */
+	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
+			cmd.args[4] << 0;
 
-	/* Si2158 requires firmware download */
-	if (chip == 58) {
-		if (((cmd.args[1] & 0x0f) == 1) && (cmd.args[3] == '2') &&
-				(cmd.args[4] == '0'))
-			fw_file = SI2158_A20_FIRMWARE;
-		else {
-			dev_err(&s->client->dev,
-					"%s: no firmware file for Si%d-%c%c defined\n",
-					KBUILD_MODNAME, chip, cmd.args[3], cmd.args[4]);
-			ret = -EINVAL;
-			goto err;
-		}
+	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
+	#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
 
-		/* cold state - try to download firmware */
-		dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
-				KBUILD_MODNAME, si2157_ops.info.name);
+	switch (chip_id) {
+	case SI2158_A20:
+		fw_file = SI2158_A20_FIRMWARE;
+		break;
+	case SI2157_A30:
+		goto skip_fw_download;
+		break;
+	default:
+		dev_err(&s->client->dev,
+				"%s: unkown chip version Si21%d-%c%c%c\n",
+				KBUILD_MODNAME, cmd.args[2], cmd.args[1],
+				cmd.args[3], cmd.args[4]);
+		ret = -EINVAL;
+		goto err;
+	}
 
-		/* request the firmware, this will block and timeout */
-		ret = request_firmware(&fw, fw_file, &s->client->dev);
-		if (ret) {
-			dev_err(&s->client->dev, "%s: firmware file '%s' not found\n",
-					KBUILD_MODNAME, fw_file);
-			goto err;
-		}
+	/* cold state - try to download firmware */
+	dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
+			KBUILD_MODNAME, si2157_ops.info.name);
 
-		dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
+	/* request the firmware, this will block and timeout */
+	ret = request_firmware(&fw, fw_file, &s->client->dev);
+	if (ret) {
+		dev_err(&s->client->dev, "%s: firmware file '%s' not found\n",
 				KBUILD_MODNAME, fw_file);
+		goto err;
+	}
 
-		/* firmware should be n chunks of 17 bytes */
-		if (fw->size % 17 != 0) {
-			dev_err(&s->client->dev, "%s: firmware file '%s' is invalid\n",
-					KBUILD_MODNAME, fw_file);
-			ret = -EINVAL;
-			goto err;
-		}
-
-		for (remaining = fw->size; remaining > 0; remaining -= 17) {
-			memcpy(&len, &fw->data[fw->size - remaining], 1);
-			memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1],
-					len);
-			cmd.wlen = len;
-			cmd.rlen = 1;
-			ret = si2157_cmd_execute(s, &cmd);
-			if (ret) {
-				dev_err(&s->client->dev,
-						"%s: firmware download failed=%d\n",
-						KBUILD_MODNAME, ret);
-				goto err;
-			}
-		}
+	/* firmware should be n chunks of 17 bytes */
+	if (fw->size % 17 != 0) {
+		dev_err(&s->client->dev, "%s: firmware file '%s' is invalid\n",
+				KBUILD_MODNAME, fw_file);
+		ret = -EINVAL;
+		goto err;
+	}
 
-		release_firmware(fw);
-		fw = NULL;
+	dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
+			KBUILD_MODNAME, fw_file);
 
+	for (remaining = fw->size; remaining > 0; remaining -= 17) {
+		len = fw->data[fw->size - remaining];
+		memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
+		cmd.wlen = len;
+		cmd.rlen = 1;
+		ret = si2157_cmd_execute(s, &cmd);
+		if (ret) {
+			dev_err(&s->client->dev,
+					"%s: firmware download failed=%d\n",
+					KBUILD_MODNAME, ret);
+			goto err;
+		}
 	}
 
+	release_firmware(fw);
+	fw = NULL;
+
+skip_fw_download:
 	/* reboot the tuner with new firmware? */
 	memcpy(cmd.args, "\x01\x01", 2);
 	cmd.wlen = 2;
@@ -176,6 +181,9 @@ static int si2157_init(struct dvb_frontend *fe)
 
 	return 0;
 err:
+	if (fw)
+		release_firmware(fw);
+
 	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
 	return ret;
 }
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 14/18] cxusb: TechnoTrend CT2-4400 USB DVB-T2/C tuner support
  2014-07-14 17:08 ` [PATCH 14/18] cxusb: TechnoTrend CT2-4400 USB DVB-T2/C tuner support Antti Palosaari
@ 2014-07-14 17:19   ` Michael Ira Krufky
  2014-07-14 17:25     ` Antti Palosaari
  0 siblings, 1 reply; 20+ messages in thread
From: Michael Ira Krufky @ 2014-07-14 17:19 UTC (permalink / raw)
  To: Antti Palosaari; +Cc: linux-media, Olli Salonen

Reviewed-by: Michael Ira Krufky <mkrufky@linuxtv.org>

I assume you'll merge this via your own branch?

...I've been traveling on & off for the past few months, but I am back
now - I'll be getting thru my pending patch queue right away

Cheers,

Mike

On Mon, Jul 14, 2014 at 1:08 PM, Antti Palosaari <crope@iki.fi> wrote:
> From: Olli Salonen <olli.salonen@iki.fi>
>
> USB ID 0b48:3014.
>
> USB interface: Cypress CY7C68013A-56LTXC
> Demodulator: Silicon Labs Si2168-30
> Tuner: Silicon Labs Si2158-20
>
> Cc: Michael Krufky <mkrufky@linuxtv.org>
> Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
> Reviewed-by: Antti Palosaari <crope@iki.fi>
> Signed-off-by: Antti Palosaari <crope@iki.fi>
> ---
>  drivers/media/dvb-core/dvb-usb-ids.h |   1 +
>  drivers/media/usb/dvb-usb/Kconfig    |   3 +
>  drivers/media/usb/dvb-usb/cxusb.c    | 191 ++++++++++++++++++++++++++++++++++-
>  drivers/media/usb/dvb-usb/cxusb.h    |   2 +
>  4 files changed, 196 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
> index 11d2bea..f8e3150 100644
> --- a/drivers/media/dvb-core/dvb-usb-ids.h
> +++ b/drivers/media/dvb-core/dvb-usb-ids.h
> @@ -244,6 +244,7 @@
>  #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
>  #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM     0x3009
>  #define USB_PID_TECHNOTREND_CONNECT_CT3650             0x300d
> +#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400           0x3014
>  #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY       0x005a
>  #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2     0x0081
>  #define USB_PID_TERRATEC_CINERGY_HT_USB_XE             0x0058
> diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
> index c5d9566..10aef21 100644
> --- a/drivers/media/usb/dvb-usb/Kconfig
> +++ b/drivers/media/usb/dvb-usb/Kconfig
> @@ -117,10 +117,12 @@ config DVB_USB_CXUSB
>         select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
>         select DVB_ATBM8830 if MEDIA_SUBDRV_AUTOSELECT
>         select DVB_LGS8GXX if MEDIA_SUBDRV_AUTOSELECT
> +       select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
>         select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
>         select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
>         select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
>         select MEDIA_TUNER_MAX2165 if MEDIA_SUBDRV_AUTOSELECT
> +       select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
>         help
>           Say Y here to support the Conexant USB2.0 hybrid reference design.
>           Currently, only DVB and ATSC modes are supported, analog mode
> @@ -128,6 +130,7 @@ config DVB_USB_CXUSB
>
>           Medion MD95700 hybrid USB2.0 device.
>           DViCO FusionHDTV (Bluebird) USB2.0 devices
> +         TechnoTrend TVStick CT2-4400
>
>  config DVB_USB_M920X
>         tristate "Uli m920x DVB-T USB2.0 support"
> diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
> index a1c641e..ad20c39 100644
> --- a/drivers/media/usb/dvb-usb/cxusb.c
> +++ b/drivers/media/usb/dvb-usb/cxusb.c
> @@ -42,6 +42,8 @@
>  #include "dib0070.h"
>  #include "lgs8gxx.h"
>  #include "atbm8830.h"
> +#include "si2168.h"
> +#include "si2157.h"
>
>  /* Max transfer size done by I2C transfer functions */
>  #define MAX_XFER_SIZE  64
> @@ -144,6 +146,22 @@ static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
>         }
>  }
>
> +static int cxusb_tt_ct2_4400_gpio_tuner(struct dvb_usb_device *d, int onoff)
> +{
> +       u8 o[2], i;
> +       int rc;
> +
> +       o[0] = 0x83;
> +       o[1] = onoff;
> +       rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
> +
> +       if (rc) {
> +               deb_info("gpio_write failed.\n");
> +               return -EIO;
> +       }
> +       return 0;
> +}
> +
>  /* I2C */
>  static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
>                           int num)
> @@ -505,6 +523,30 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
>         return 0;
>  }
>
> +static int cxusb_tt_ct2_4400_rc_query(struct dvb_usb_device *d)
> +{
> +       u8 i[2];
> +       int ret;
> +       u32 cmd, keycode;
> +       u8 rc5_cmd, rc5_addr, rc5_toggle;
> +
> +       ret = cxusb_ctrl_msg(d, 0x10, NULL, 0, i, 2);
> +       if (ret)
> +               return ret;
> +
> +       cmd = (i[0] << 8) | i[1];
> +
> +       if (cmd != 0xffff) {
> +               rc5_cmd = cmd & 0x3F; /* bits 1-6 for command */
> +               rc5_addr = (cmd & 0x07C0) >> 6; /* bits 7-11 for address */
> +               rc5_toggle = (cmd & 0x0800) >> 11; /* bit 12 for toggle */
> +               keycode = (rc5_addr << 8) | rc5_cmd;
> +               rc_keydown(d->rc_dev, keycode, rc5_toggle);
> +       }
> +
> +       return 0;
> +}
> +
>  static struct rc_map_table rc_map_dvico_mce_table[] = {
>         { 0xfe02, KEY_TV },
>         { 0xfe0e, KEY_MP3 },
> @@ -1286,6 +1328,73 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
>         return 0;
>  }
>
> +static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap)
> +{
> +       struct dvb_usb_device *d = adap->dev;
> +       struct cxusb_state *st = d->priv;
> +       struct i2c_adapter *adapter;
> +       struct i2c_client *client_demod;
> +       struct i2c_client *client_tuner;
> +       struct i2c_board_info info;
> +       struct si2168_config si2168_config;
> +       struct si2157_config si2157_config;
> +
> +       /* reset the tuner */
> +       if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) {
> +               err("clear tuner gpio failed");
> +               return -EIO;
> +       }
> +       msleep(100);
> +       if (cxusb_tt_ct2_4400_gpio_tuner(d, 1) < 0) {
> +               err("set tuner gpio failed");
> +               return -EIO;
> +       }
> +       msleep(100);
> +
> +       /* attach frontend */
> +       si2168_config.i2c_adapter = &adapter;
> +       si2168_config.fe = &adap->fe_adap[0].fe;
> +       memset(&info, 0, sizeof(struct i2c_board_info));
> +       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
> +       info.addr = 0x64;
> +       info.platform_data = &si2168_config;
> +       request_module(info.type);
> +       client_demod = i2c_new_device(&d->i2c_adap, &info);
> +       if (client_demod == NULL || client_demod->dev.driver == NULL)
> +               return -ENODEV;
> +
> +       if (!try_module_get(client_demod->dev.driver->owner)) {
> +               i2c_unregister_device(client_demod);
> +               return -ENODEV;
> +       }
> +
> +       st->i2c_client_demod = client_demod;
> +
> +       /* attach tuner */
> +       si2157_config.fe = adap->fe_adap[0].fe;
> +       memset(&info, 0, sizeof(struct i2c_board_info));
> +       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
> +       info.addr = 0x60;
> +       info.platform_data = &si2157_config;
> +       request_module(info.type);
> +       client_tuner = i2c_new_device(adapter, &info);
> +       if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
> +               module_put(client_demod->dev.driver->owner);
> +               i2c_unregister_device(client_demod);
> +               return -ENODEV;
> +       }
> +       if (!try_module_get(client_tuner->dev.driver->owner)) {
> +               i2c_unregister_device(client_tuner);
> +               module_put(client_demod->dev.driver->owner);
> +               i2c_unregister_device(client_demod);
> +               return -ENODEV;
> +       }
> +
> +       st->i2c_client_tuner = client_tuner;
> +
> +       return 0;
> +}
> +
>  /*
>   * DViCO has shipped two devices with the same USB ID, but only one of them
>   * needs a firmware download.  Check the device class details to see if they
> @@ -1367,6 +1476,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
>  static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
>  static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
>  static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
> +static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties;
>
>  static int cxusb_probe(struct usb_interface *intf,
>                        const struct usb_device_id *id)
> @@ -1397,12 +1507,37 @@ static int cxusb_probe(struct usb_interface *intf,
>                                      THIS_MODULE, NULL, adapter_nr) ||
>             0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
>                                      THIS_MODULE, NULL, adapter_nr) ||
> +           0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties,
> +                                    THIS_MODULE, NULL, adapter_nr) ||
>             0)
>                 return 0;
>
>         return -EINVAL;
>  }
>
> +static void cxusb_disconnect(struct usb_interface *intf)
> +{
> +       struct dvb_usb_device *d = usb_get_intfdata(intf);
> +       struct cxusb_state *st = d->priv;
> +       struct i2c_client *client;
> +
> +       /* remove I2C client for tuner */
> +       client = st->i2c_client_tuner;
> +       if (client) {
> +               module_put(client->dev.driver->owner);
> +               i2c_unregister_device(client);
> +       }
> +
> +       /* remove I2C client for demodulator */
> +       client = st->i2c_client_demod;
> +       if (client) {
> +               module_put(client->dev.driver->owner);
> +               i2c_unregister_device(client);
> +       }
> +
> +       dvb_usb_device_exit(intf);
> +}
> +
>  static struct usb_device_id cxusb_table [] = {
>         { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
>         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
> @@ -1424,6 +1559,7 @@ static struct usb_device_id cxusb_table [] = {
>         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
>         { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
>         { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
> +       { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) },
>         {}              /* Terminating entry */
>  };
>  MODULE_DEVICE_TABLE (usb, cxusb_table);
> @@ -2070,10 +2206,63 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
>         }
>  };
>
> +static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = {
> +       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
> +
> +       .usb_ctrl         = CYPRESS_FX2,
> +
> +       .size_of_priv     = sizeof(struct cxusb_state),
> +
> +       .num_adapters = 1,
> +       .adapter = {
> +               {
> +               .num_frontends = 1,
> +               .fe = {{
> +                       .streaming_ctrl   = cxusb_streaming_ctrl,
> +                       /* both frontend and tuner attached in the
> +                          same function */
> +                       .frontend_attach  = cxusb_tt_ct2_4400_attach,
> +
> +                       /* parameter for the MPEG2-data transfer */
> +                       .stream = {
> +                               .type = USB_BULK,
> +                               .count = 8,
> +                               .endpoint = 0x82,
> +                               .u = {
> +                                       .bulk = {
> +                                               .buffersize = 4096,
> +                                       }
> +                               }
> +                       },
> +               } },
> +               },
> +       },
> +
> +       .i2c_algo = &cxusb_i2c_algo,
> +       .generic_bulk_ctrl_endpoint = 0x01,
> +       .generic_bulk_ctrl_endpoint_response = 0x81,
> +
> +       .rc.core = {
> +               .rc_codes       = RC_MAP_TT_1500,
> +               .allowed_protos = RC_BIT_RC5,
> +               .rc_query       = cxusb_tt_ct2_4400_rc_query,
> +               .rc_interval    = 150,
> +       },
> +
> +       .num_device_descs = 1,
> +       .devices = {
> +               {
> +                       "TechnoTrend TVStick CT2-4400",
> +                       { NULL },
> +                       { &cxusb_table[20], NULL },
> +               },
> +       }
> +};
> +
>  static struct usb_driver cxusb_driver = {
>         .name           = "dvb_usb_cxusb",
>         .probe          = cxusb_probe,
> -       .disconnect     = dvb_usb_device_exit,
> +       .disconnect     = cxusb_disconnect,
>         .id_table       = cxusb_table,
>  };
>
> diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
> index 1a51eaf..527ff79 100644
> --- a/drivers/media/usb/dvb-usb/cxusb.h
> +++ b/drivers/media/usb/dvb-usb/cxusb.h
> @@ -30,6 +30,8 @@
>
>  struct cxusb_state {
>         u8 gpio_write_state[3];
> +       struct i2c_client *i2c_client_demod;
> +       struct i2c_client *i2c_client_tuner;
>  };
>
>  #endif
> --
> 1.9.3
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 14/18] cxusb: TechnoTrend CT2-4400 USB DVB-T2/C tuner support
  2014-07-14 17:19   ` Michael Ira Krufky
@ 2014-07-14 17:25     ` Antti Palosaari
  0 siblings, 0 replies; 20+ messages in thread
From: Antti Palosaari @ 2014-07-14 17:25 UTC (permalink / raw)
  To: Michael Ira Krufky; +Cc: linux-media, Olli Salonen

On 07/14/2014 08:19 PM, Michael Ira Krufky wrote:
> Reviewed-by: Michael Ira Krufky <mkrufky@linuxtv.org>
>
> I assume you'll merge this via your own branch?
>
> ...I've been traveling on & off for the past few months, but I am back
> now - I'll be getting thru my pending patch queue right away

Yes, because all those remaining patches were si2168 and si2157 drivers 
(demod and tuner). I will add you Reviewed-by tag and update PULL 
request. Thanks!

regards
Antti

>
> Cheers,
>
> Mike
>
> On Mon, Jul 14, 2014 at 1:08 PM, Antti Palosaari <crope@iki.fi> wrote:
>> From: Olli Salonen <olli.salonen@iki.fi>
>>
>> USB ID 0b48:3014.
>>
>> USB interface: Cypress CY7C68013A-56LTXC
>> Demodulator: Silicon Labs Si2168-30
>> Tuner: Silicon Labs Si2158-20
>>
>> Cc: Michael Krufky <mkrufky@linuxtv.org>
>> Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
>> Reviewed-by: Antti Palosaari <crope@iki.fi>
>> Signed-off-by: Antti Palosaari <crope@iki.fi>
>> ---
>>   drivers/media/dvb-core/dvb-usb-ids.h |   1 +
>>   drivers/media/usb/dvb-usb/Kconfig    |   3 +
>>   drivers/media/usb/dvb-usb/cxusb.c    | 191 ++++++++++++++++++++++++++++++++++-
>>   drivers/media/usb/dvb-usb/cxusb.h    |   2 +
>>   4 files changed, 196 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
>> index 11d2bea..f8e3150 100644
>> --- a/drivers/media/dvb-core/dvb-usb-ids.h
>> +++ b/drivers/media/dvb-core/dvb-usb-ids.h
>> @@ -244,6 +244,7 @@
>>   #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
>>   #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM     0x3009
>>   #define USB_PID_TECHNOTREND_CONNECT_CT3650             0x300d
>> +#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400           0x3014
>>   #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY       0x005a
>>   #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2     0x0081
>>   #define USB_PID_TERRATEC_CINERGY_HT_USB_XE             0x0058
>> diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
>> index c5d9566..10aef21 100644
>> --- a/drivers/media/usb/dvb-usb/Kconfig
>> +++ b/drivers/media/usb/dvb-usb/Kconfig
>> @@ -117,10 +117,12 @@ config DVB_USB_CXUSB
>>          select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
>>          select DVB_ATBM8830 if MEDIA_SUBDRV_AUTOSELECT
>>          select DVB_LGS8GXX if MEDIA_SUBDRV_AUTOSELECT
>> +       select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
>>          select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
>>          select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
>>          select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
>>          select MEDIA_TUNER_MAX2165 if MEDIA_SUBDRV_AUTOSELECT
>> +       select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
>>          help
>>            Say Y here to support the Conexant USB2.0 hybrid reference design.
>>            Currently, only DVB and ATSC modes are supported, analog mode
>> @@ -128,6 +130,7 @@ config DVB_USB_CXUSB
>>
>>            Medion MD95700 hybrid USB2.0 device.
>>            DViCO FusionHDTV (Bluebird) USB2.0 devices
>> +         TechnoTrend TVStick CT2-4400
>>
>>   config DVB_USB_M920X
>>          tristate "Uli m920x DVB-T USB2.0 support"
>> diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
>> index a1c641e..ad20c39 100644
>> --- a/drivers/media/usb/dvb-usb/cxusb.c
>> +++ b/drivers/media/usb/dvb-usb/cxusb.c
>> @@ -42,6 +42,8 @@
>>   #include "dib0070.h"
>>   #include "lgs8gxx.h"
>>   #include "atbm8830.h"
>> +#include "si2168.h"
>> +#include "si2157.h"
>>
>>   /* Max transfer size done by I2C transfer functions */
>>   #define MAX_XFER_SIZE  64
>> @@ -144,6 +146,22 @@ static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
>>          }
>>   }
>>
>> +static int cxusb_tt_ct2_4400_gpio_tuner(struct dvb_usb_device *d, int onoff)
>> +{
>> +       u8 o[2], i;
>> +       int rc;
>> +
>> +       o[0] = 0x83;
>> +       o[1] = onoff;
>> +       rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
>> +
>> +       if (rc) {
>> +               deb_info("gpio_write failed.\n");
>> +               return -EIO;
>> +       }
>> +       return 0;
>> +}
>> +
>>   /* I2C */
>>   static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
>>                            int num)
>> @@ -505,6 +523,30 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
>>          return 0;
>>   }
>>
>> +static int cxusb_tt_ct2_4400_rc_query(struct dvb_usb_device *d)
>> +{
>> +       u8 i[2];
>> +       int ret;
>> +       u32 cmd, keycode;
>> +       u8 rc5_cmd, rc5_addr, rc5_toggle;
>> +
>> +       ret = cxusb_ctrl_msg(d, 0x10, NULL, 0, i, 2);
>> +       if (ret)
>> +               return ret;
>> +
>> +       cmd = (i[0] << 8) | i[1];
>> +
>> +       if (cmd != 0xffff) {
>> +               rc5_cmd = cmd & 0x3F; /* bits 1-6 for command */
>> +               rc5_addr = (cmd & 0x07C0) >> 6; /* bits 7-11 for address */
>> +               rc5_toggle = (cmd & 0x0800) >> 11; /* bit 12 for toggle */
>> +               keycode = (rc5_addr << 8) | rc5_cmd;
>> +               rc_keydown(d->rc_dev, keycode, rc5_toggle);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>>   static struct rc_map_table rc_map_dvico_mce_table[] = {
>>          { 0xfe02, KEY_TV },
>>          { 0xfe0e, KEY_MP3 },
>> @@ -1286,6 +1328,73 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
>>          return 0;
>>   }
>>
>> +static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap)
>> +{
>> +       struct dvb_usb_device *d = adap->dev;
>> +       struct cxusb_state *st = d->priv;
>> +       struct i2c_adapter *adapter;
>> +       struct i2c_client *client_demod;
>> +       struct i2c_client *client_tuner;
>> +       struct i2c_board_info info;
>> +       struct si2168_config si2168_config;
>> +       struct si2157_config si2157_config;
>> +
>> +       /* reset the tuner */
>> +       if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) {
>> +               err("clear tuner gpio failed");
>> +               return -EIO;
>> +       }
>> +       msleep(100);
>> +       if (cxusb_tt_ct2_4400_gpio_tuner(d, 1) < 0) {
>> +               err("set tuner gpio failed");
>> +               return -EIO;
>> +       }
>> +       msleep(100);
>> +
>> +       /* attach frontend */
>> +       si2168_config.i2c_adapter = &adapter;
>> +       si2168_config.fe = &adap->fe_adap[0].fe;
>> +       memset(&info, 0, sizeof(struct i2c_board_info));
>> +       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
>> +       info.addr = 0x64;
>> +       info.platform_data = &si2168_config;
>> +       request_module(info.type);
>> +       client_demod = i2c_new_device(&d->i2c_adap, &info);
>> +       if (client_demod == NULL || client_demod->dev.driver == NULL)
>> +               return -ENODEV;
>> +
>> +       if (!try_module_get(client_demod->dev.driver->owner)) {
>> +               i2c_unregister_device(client_demod);
>> +               return -ENODEV;
>> +       }
>> +
>> +       st->i2c_client_demod = client_demod;
>> +
>> +       /* attach tuner */
>> +       si2157_config.fe = adap->fe_adap[0].fe;
>> +       memset(&info, 0, sizeof(struct i2c_board_info));
>> +       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
>> +       info.addr = 0x60;
>> +       info.platform_data = &si2157_config;
>> +       request_module(info.type);
>> +       client_tuner = i2c_new_device(adapter, &info);
>> +       if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
>> +               module_put(client_demod->dev.driver->owner);
>> +               i2c_unregister_device(client_demod);
>> +               return -ENODEV;
>> +       }
>> +       if (!try_module_get(client_tuner->dev.driver->owner)) {
>> +               i2c_unregister_device(client_tuner);
>> +               module_put(client_demod->dev.driver->owner);
>> +               i2c_unregister_device(client_demod);
>> +               return -ENODEV;
>> +       }
>> +
>> +       st->i2c_client_tuner = client_tuner;
>> +
>> +       return 0;
>> +}
>> +
>>   /*
>>    * DViCO has shipped two devices with the same USB ID, but only one of them
>>    * needs a firmware download.  Check the device class details to see if they
>> @@ -1367,6 +1476,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
>>   static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
>>   static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
>>   static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
>> +static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties;
>>
>>   static int cxusb_probe(struct usb_interface *intf,
>>                         const struct usb_device_id *id)
>> @@ -1397,12 +1507,37 @@ static int cxusb_probe(struct usb_interface *intf,
>>                                       THIS_MODULE, NULL, adapter_nr) ||
>>              0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
>>                                       THIS_MODULE, NULL, adapter_nr) ||
>> +           0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties,
>> +                                    THIS_MODULE, NULL, adapter_nr) ||
>>              0)
>>                  return 0;
>>
>>          return -EINVAL;
>>   }
>>
>> +static void cxusb_disconnect(struct usb_interface *intf)
>> +{
>> +       struct dvb_usb_device *d = usb_get_intfdata(intf);
>> +       struct cxusb_state *st = d->priv;
>> +       struct i2c_client *client;
>> +
>> +       /* remove I2C client for tuner */
>> +       client = st->i2c_client_tuner;
>> +       if (client) {
>> +               module_put(client->dev.driver->owner);
>> +               i2c_unregister_device(client);
>> +       }
>> +
>> +       /* remove I2C client for demodulator */
>> +       client = st->i2c_client_demod;
>> +       if (client) {
>> +               module_put(client->dev.driver->owner);
>> +               i2c_unregister_device(client);
>> +       }
>> +
>> +       dvb_usb_device_exit(intf);
>> +}
>> +
>>   static struct usb_device_id cxusb_table [] = {
>>          { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
>>          { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
>> @@ -1424,6 +1559,7 @@ static struct usb_device_id cxusb_table [] = {
>>          { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
>>          { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
>>          { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
>> +       { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) },
>>          {}              /* Terminating entry */
>>   };
>>   MODULE_DEVICE_TABLE (usb, cxusb_table);
>> @@ -2070,10 +2206,63 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
>>          }
>>   };
>>
>> +static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = {
>> +       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
>> +
>> +       .usb_ctrl         = CYPRESS_FX2,
>> +
>> +       .size_of_priv     = sizeof(struct cxusb_state),
>> +
>> +       .num_adapters = 1,
>> +       .adapter = {
>> +               {
>> +               .num_frontends = 1,
>> +               .fe = {{
>> +                       .streaming_ctrl   = cxusb_streaming_ctrl,
>> +                       /* both frontend and tuner attached in the
>> +                          same function */
>> +                       .frontend_attach  = cxusb_tt_ct2_4400_attach,
>> +
>> +                       /* parameter for the MPEG2-data transfer */
>> +                       .stream = {
>> +                               .type = USB_BULK,
>> +                               .count = 8,
>> +                               .endpoint = 0x82,
>> +                               .u = {
>> +                                       .bulk = {
>> +                                               .buffersize = 4096,
>> +                                       }
>> +                               }
>> +                       },
>> +               } },
>> +               },
>> +       },
>> +
>> +       .i2c_algo = &cxusb_i2c_algo,
>> +       .generic_bulk_ctrl_endpoint = 0x01,
>> +       .generic_bulk_ctrl_endpoint_response = 0x81,
>> +
>> +       .rc.core = {
>> +               .rc_codes       = RC_MAP_TT_1500,
>> +               .allowed_protos = RC_BIT_RC5,
>> +               .rc_query       = cxusb_tt_ct2_4400_rc_query,
>> +               .rc_interval    = 150,
>> +       },
>> +
>> +       .num_device_descs = 1,
>> +       .devices = {
>> +               {
>> +                       "TechnoTrend TVStick CT2-4400",
>> +                       { NULL },
>> +                       { &cxusb_table[20], NULL },
>> +               },
>> +       }
>> +};
>> +
>>   static struct usb_driver cxusb_driver = {
>>          .name           = "dvb_usb_cxusb",
>>          .probe          = cxusb_probe,
>> -       .disconnect     = dvb_usb_device_exit,
>> +       .disconnect     = cxusb_disconnect,
>>          .id_table       = cxusb_table,
>>   };
>>
>> diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
>> index 1a51eaf..527ff79 100644
>> --- a/drivers/media/usb/dvb-usb/cxusb.h
>> +++ b/drivers/media/usb/dvb-usb/cxusb.h
>> @@ -30,6 +30,8 @@
>>
>>   struct cxusb_state {
>>          u8 gpio_write_state[3];
>> +       struct i2c_client *i2c_client_demod;
>> +       struct i2c_client *i2c_client_tuner;
>>   };
>>
>>   #endif
>> --
>> 1.9.3
>>

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2014-07-14 17:25 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-14 17:08 [PATCH 01/18] si2157: implement sleep Antti Palosaari
2014-07-14 17:08 ` [PATCH 02/18] si2168: " Antti Palosaari
2014-07-14 17:08 ` [PATCH 03/18] si2168: set cmd args using memcpy Antti Palosaari
2014-07-14 17:08 ` [PATCH 04/18] si2168: implement CNR statistic Antti Palosaari
2014-07-14 17:08 ` [PATCH 05/18] si2157: add read data support for fw cmd func Antti Palosaari
2014-07-14 17:08 ` [PATCH 06/18] si2168: remove duplicate command Antti Palosaari
2014-07-14 17:08 ` [PATCH 07/18] si2168: do not set values which are already on default Antti Palosaari
2014-07-14 17:08 ` [PATCH 08/18] si2168: receive 4 bytes reply from cmd 0x14 Antti Palosaari
2014-07-14 17:08 ` [PATCH 09/18] si2168: Small typo fix (SI2157 -> SI2168) Antti Palosaari
2014-07-14 17:08 ` [PATCH 10/18] si2168: Add support for chip revision Si2168 A30 Antti Palosaari
2014-07-14 17:08 ` [PATCH 11/18] si2157: Move chip initialization to si2157_init Antti Palosaari
2014-07-14 17:08 ` [PATCH 12/18] si2157: Add support for Si2158 chip Antti Palosaari
2014-07-14 17:08 ` [PATCH 13/18] si2157: Set delivery system and bandwidth before tuning Antti Palosaari
2014-07-14 17:08 ` [PATCH 14/18] cxusb: TechnoTrend CT2-4400 USB DVB-T2/C tuner support Antti Palosaari
2014-07-14 17:19   ` Michael Ira Krufky
2014-07-14 17:25     ` Antti Palosaari
2014-07-14 17:08 ` [PATCH 15/18] si2168: advertise Si2168 A30 firmware Antti Palosaari
2014-07-14 17:08 ` [PATCH 16/18] si2157: advertise Si2158 A20 firmware Antti Palosaari
2014-07-14 17:08 ` [PATCH 17/18] si2168: few firmware download changes Antti Palosaari
2014-07-14 17:08 ` [PATCH 18/18] si2157: rework firmware download logic a little bit Antti Palosaari

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).