Hello,

Thank you for your patch.

On Thu, Jan 10, 2019 at 06:56:23PM +0900, tsk...@gmail.com wrote:
> From: Akihiro Tsukada <tsk...@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 <tsk...@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

Reply via email to