Linux-Media Archive on lore.kernel.org
 help / Atom feed
* [PATCH] media: dvb/earth-pt1: fix wrong initialization for demod blocks
@ 2019-01-10  9:56 tskd08
  2019-02-18 21:04 ` Sean Young
  0 siblings, 1 reply; 3+ messages in thread
From: tskd08 @ 2019-01-10  9:56 UTC (permalink / raw)
  To: linux-media; +Cc: mchehab, Akihiro Tsukada

From: Akihiro Tsukada <tskd08@gmail.com>

earth-pt1 driver was decomposed/restructured by the commit: b732539efdba
("media: dvb: earth-pt1: decompose pt1 driver into sub drivers"),
but it introduced a problem regarding concurrent streaming:
Opening a new terrestial stream stops the reception of an existing,
already-opened satellite stream.

The demod IC in earth-pt1 boards contains 2 pairs of terr. and sat. blocks,
supporting 4 concurrent demodulations, and the above problem was because
the config of a terr. block contained whole reset/init of the pair blocks,
thus each open() of a terrestrial frontend wrongly cleared the config of
its peer satellite block of the demod.
This whole/pair reset should be executed earlier and not on each open().

Fixes: b732539efdba ("media: dvb: earth-pt1: decompose pt1 driver into sub drivers")
Signed-off-by: Akihiro Tsukada <tskd08@gmail.com>
---
 drivers/media/pci/pt1/pt1.c | 54 ++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 6 deletions(-)

diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index f4b8030e236..403f88ee3d9 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -200,16 +200,10 @@ static const u8 va1j5jf8007t_25mhz_configs[][2] = {
 static int config_demod(struct i2c_client *cl, enum pt1_fe_clk clk)
 {
 	int ret;
-	u8 buf[2] = {0x01, 0x80};
 	bool is_sat;
 	const u8 (*cfg_data)[2];
 	int i, len;
 
-	ret = i2c_master_send(cl, buf, 2);
-	if (ret < 0)
-		return ret;
-	usleep_range(30000, 50000);
-
 	is_sat = !strncmp(cl->name, TC90522_I2C_DEV_SAT,
 			  strlen(TC90522_I2C_DEV_SAT));
 	if (is_sat) {
@@ -260,6 +254,46 @@ static int config_demod(struct i2c_client *cl, enum pt1_fe_clk clk)
 	return 0;
 }
 
+/*
+ * Init registers for (each pair of) terrestrial/satellite block in demod.
+ * Note that resetting terr. block also resets its peer sat. block as well.
+ * This function must be called before configuring any demod block
+ * (before pt1_wakeup(), fe->ops.init()).
+ */
+static int pt1_demod_block_init(struct pt1 *pt1)
+{
+	struct i2c_client *cl;
+	u8 buf[2] = {0x01, 0x80};
+	int ret;
+	int i;
+
+	/* reset all terr. & sat. pairs first */
+	for (i = 0; i < PT1_NR_ADAPS; i++) {
+		cl = pt1->adaps[i]->demod_i2c_client;
+		if (strncmp(cl->name, TC90522_I2C_DEV_TER,
+			     strlen(TC90522_I2C_DEV_TER)))
+			continue;
+
+		ret = i2c_master_send(cl, buf, 2);
+		if (ret < 0)
+			return ret;
+		usleep_range(30000, 50000);
+	}
+
+	for (i = 0; i < PT1_NR_ADAPS; i++) {
+		cl = pt1->adaps[i]->demod_i2c_client;
+		if (strncmp(cl->name, TC90522_I2C_DEV_SAT,
+			     strlen(TC90522_I2C_DEV_SAT)))
+			continue;
+
+		ret = i2c_master_send(cl, buf, 2);
+		if (ret < 0)
+			return ret;
+		usleep_range(30000, 50000);
+	}
+	return 0;
+}
+
 static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data)
 {
 	writel(data, pt1->regs + reg * 4);
@@ -987,6 +1021,10 @@ static int pt1_init_frontends(struct pt1 *pt1)
 			goto tuner_release;
 	}
 
+	ret = pt1_demod_block_init(pt1);
+	if (ret < 0)
+		goto fe_unregister;
+
 	return 0;
 
 tuner_release:
@@ -1245,6 +1283,10 @@ static int pt1_resume(struct device *dev)
 	pt1_update_power(pt1);
 	usleep_range(1000, 2000);
 
+	ret = pt1_demod_block_init(pt1);
+	if (ret < 0)
+		goto resume_err;
+
 	for (i = 0; i < PT1_NR_ADAPS; i++)
 		dvb_frontend_reinitialise(pt1->adaps[i]->fe);
 
-- 
2.20.1


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

* Re: [PATCH] media: dvb/earth-pt1: fix wrong initialization for demod blocks
  2019-01-10  9:56 [PATCH] media: dvb/earth-pt1: fix wrong initialization for demod blocks tskd08
@ 2019-02-18 21:04 ` Sean Young
  0 siblings, 0 replies; 3+ messages in thread
From: Sean Young @ 2019-02-18 21:04 UTC (permalink / raw)
  To: tskd08; +Cc: linux-media, mchehab

Hello,

Thank you for your patch.

On Thu, Jan 10, 2019 at 06:56:23PM +0900, tskd08@gmail.com wrote:
> From: Akihiro Tsukada <tskd08@gmail.com>
> 
> earth-pt1 driver was decomposed/restructured by the commit: b732539efdba
> ("media: dvb: earth-pt1: decompose pt1 driver into sub drivers"),
> but it introduced a problem regarding concurrent streaming:
> Opening a new terrestial stream stops the reception of an existing,
> already-opened satellite stream.
> 
> The demod IC in earth-pt1 boards contains 2 pairs of terr. and sat. blocks,
> supporting 4 concurrent demodulations, and the above problem was because
> the config of a terr. block contained whole reset/init of the pair blocks,
> thus each open() of a terrestrial frontend wrongly cleared the config of
> its peer satellite block of the demod.
> This whole/pair reset should be executed earlier and not on each open().
> 
> Fixes: b732539efdba ("media: dvb: earth-pt1: decompose pt1 driver into sub drivers")
> Signed-off-by: Akihiro Tsukada <tskd08@gmail.com>
> ---
>  drivers/media/pci/pt1/pt1.c | 54 ++++++++++++++++++++++++++++++++-----
>  1 file changed, 48 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
> index f4b8030e236..403f88ee3d9 100644
> --- a/drivers/media/pci/pt1/pt1.c
> +++ b/drivers/media/pci/pt1/pt1.c
> @@ -200,16 +200,10 @@ static const u8 va1j5jf8007t_25mhz_configs[][2] = {
>  static int config_demod(struct i2c_client *cl, enum pt1_fe_clk clk)
>  {
>  	int ret;
> -	u8 buf[2] = {0x01, 0x80};
>  	bool is_sat;
>  	const u8 (*cfg_data)[2];
>  	int i, len;
>  
> -	ret = i2c_master_send(cl, buf, 2);
> -	if (ret < 0)
> -		return ret;
> -	usleep_range(30000, 50000);
> -
>  	is_sat = !strncmp(cl->name, TC90522_I2C_DEV_SAT,
>  			  strlen(TC90522_I2C_DEV_SAT));
>  	if (is_sat) {
> @@ -260,6 +254,46 @@ static int config_demod(struct i2c_client *cl, enum pt1_fe_clk clk)
>  	return 0;
>  }
>  
> +/*
> + * Init registers for (each pair of) terrestrial/satellite block in demod.
> + * Note that resetting terr. block also resets its peer sat. block as well.
> + * This function must be called before configuring any demod block
> + * (before pt1_wakeup(), fe->ops.init()).
> + */
> +static int pt1_demod_block_init(struct pt1 *pt1)
> +{
> +	struct i2c_client *cl;
> +	u8 buf[2] = {0x01, 0x80};
> +	int ret;
> +	int i;
> +
> +	/* reset all terr. & sat. pairs first */
> +	for (i = 0; i < PT1_NR_ADAPS; i++) {
> +		cl = pt1->adaps[i]->demod_i2c_client;
> +		if (strncmp(cl->name, TC90522_I2C_DEV_TER,
> +			     strlen(TC90522_I2C_DEV_TER)))
> +			continue;
> +
> +		ret = i2c_master_send(cl, buf, 2);
> +		if (ret < 0)
> +			return ret;
> +		usleep_range(30000, 50000);
> +	}
> +
> +	for (i = 0; i < PT1_NR_ADAPS; i++) {
> +		cl = pt1->adaps[i]->demod_i2c_client;
> +		if (strncmp(cl->name, TC90522_I2C_DEV_SAT,
> +			     strlen(TC90522_I2C_DEV_SAT)))
> +			continue;
> +
> +		ret = i2c_master_send(cl, buf, 2);
> +		if (ret < 0)
> +			return ret;
> +		usleep_range(30000, 50000);
> +	}

It might be possible to simplify the code a little by using strcmp() and
making it into one loop, like so:

	for (i = 0; i < PT1_NR_ADAPS; i++) {
		cl = pt1->adaps[i]->demod_i2c_client;
		if (strcmp(cl->name, TC90522_I2C_DEV_SAT) &&
		    strcmp(cl->name, TC90522_I2C_DEV_TER)) 
			continue;

		ret = i2c_master_send(cl, buf, 2);
		if (ret < 0)
			return ret;

		usleep_range(30000, 50000);
	}


> +	return 0;
> +}
> +
>  static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data)
>  {
>  	writel(data, pt1->regs + reg * 4);
> @@ -987,6 +1021,10 @@ static int pt1_init_frontends(struct pt1 *pt1)
>  			goto tuner_release;
>  	}
>  
> +	ret = pt1_demod_block_init(pt1);
> +	if (ret < 0)
> +		goto fe_unregister;
> +
>  	return 0;
>  
>  tuner_release:
> @@ -1245,6 +1283,10 @@ static int pt1_resume(struct device *dev)
>  	pt1_update_power(pt1);
>  	usleep_range(1000, 2000);
>  
> +	ret = pt1_demod_block_init(pt1);
> +	if (ret < 0)
> +		goto resume_err;
> +
>  	for (i = 0; i < PT1_NR_ADAPS; i++)
>  		dvb_frontend_reinitialise(pt1->adaps[i]->fe);
>  
> -- 
> 2.20.1

Many thanks,

Sean

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

* Re: [PATCH] media: dvb/earth-pt1: fix wrong initialization for demod blocks
@ 2019-02-21 14:47 Akihiro TSUKADA
  0 siblings, 0 replies; 3+ messages in thread
From: Akihiro TSUKADA @ 2019-02-21 14:47 UTC (permalink / raw)
  To: sean, linux-media, mchehab

Hi,
thank you for reviewing my patch,
 ( <20190110095623.28070-1-tskd08@gmail.com>
   https://patchwork.linuxtv.org/patch/53834/ ),
and excuse me for my late reply.
I somehow lost your mail and noticed it just today by checking Patchwork.

On Mon, 18 Feb 2019 21:04:28 +0000, you wrote:
> It might be possible to simplify the code a little by using strcmp() and
> making it into one loop, like so:
> 
> 	for (i = 0; i < PT1_NR_ADAPS; i++) {
> 		cl = pt1->adaps[i]->demod_i2c_client;
> 		if (strcmp(cl->name, TC90522_I2C_DEV_SAT) &&
> 		    strcmp(cl->name, TC90522_I2C_DEV_TER)) 
> 			continue;
> 
> 		ret = i2c_master_send(cl, buf, 2);
> 		if (ret < 0)
> 			return ret;
> 
> 		usleep_range(30000, 50000);
> 	}

Any "cl" has the name of either TC90522_I2C_DEV_SAT or TC90522_I2C_DEV_TER,
and no other name exists.  (adaps[0],adaps[2]: _SAT, adaps[1],adaps[3]: _TER)
The purpose of the code is to ensure that TER clients are processed
BEFORE SAT clients, as noted in the header comment of this function.
So I am afraid that unifying the two loops does not work.

--
Akihiro

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

end of thread, back to index

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-10  9:56 [PATCH] media: dvb/earth-pt1: fix wrong initialization for demod blocks tskd08
2019-02-18 21:04 ` Sean Young
2019-02-21 14:47 Akihiro TSUKADA

Linux-Media Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-media/0 linux-media/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-media linux-media/ https://lore.kernel.org/linux-media \
		linux-media@vger.kernel.org linux-media@archiver.kernel.org
	public-inbox-index linux-media


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-media


AGPL code for this site: git clone https://public-inbox.org/ public-inbox