On 6/16/19 8:22 PM, Johan Korsnes wrote:
> Set/invalidate physical addresses based on the configuration of the
> display present control. This is relevant not only when the display
> present control is modified, but also when the Vivid instance EDID is
> set/cleared.
> 
> Signed-off-by: Johan Korsnes <johan.kors...@gmail.com>
> ---
>  drivers/media/platform/vivid/vivid-ctrls.c    | 25 ++++++++++++++++---
>  drivers/media/platform/vivid/vivid-vid-cap.c  | 17 +++++++++++--
>  .../media/platform/vivid/vivid-vid-common.c   |  2 ++
>  3 files changed, 38 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/platform/vivid/vivid-ctrls.c 
> b/drivers/media/platform/vivid/vivid-ctrls.c
> index ae3690fd1b52..807c9e92e051 100644
> --- a/drivers/media/platform/vivid/vivid-ctrls.c
> +++ b/drivers/media/platform/vivid/vivid-ctrls.c
> @@ -18,6 +18,7 @@
>  #include "vivid-radio-common.h"
>  #include "vivid-osd.h"
>  #include "vivid-ctrls.h"
> +#include "vivid-cec.h"
>  
>  #define VIVID_CID_CUSTOM_BASE                (V4L2_CID_USER_BASE | 0xf000)
>  #define VIVID_CID_BUTTON             (VIVID_CID_CUSTOM_BASE + 0)
> @@ -923,7 +924,7 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
>       struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, 
> ctrl_hdl_vid_out);
>       struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
>       u32 display_present = 0;
> -     unsigned i, j;
> +     unsigned i, j, bus_idx;
>  
>       switch (ctrl->id) {
>       case VIVID_CID_HAS_CROP_OUT:
> @@ -962,15 +963,31 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
>                       break;
>  
>               dev->display_present[dev->output] = ctrl->val;
> -
>               for (i = 0, j = 0; i < dev->num_outputs; i++)
>                       if (dev->output_type[i] == HDMI)
>                               display_present |=
>                                       dev->display_present[i] << j++;
>  
> -             __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present);
>               __v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present);
> -             __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present);
> +
> +             if (dev->edid_blocks) {
> +                     __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present,
> +                                        display_present);
> +                     __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug,
> +                                        display_present);
> +             }
> +
> +             if (!dev->cec_tx_adap)
> +                     break;

This isn't right: cec_tx_adap is an array of cec_adapter pointers, so
dev->cec_tx_adap is always non-NULL.

Just drop it.

> +
> +             bus_idx = dev->cec_output2bus_map[dev->output];

Instead you need to do:

                if (!dev->cec_tx_adap[bus_idx])
                        break;

to ensure that the adapter for bus_idx is non-NULL.

Regards,

        Hans

> +             if (ctrl->val && dev->edid_blocks)
> +                     cec_s_phys_addr(dev->cec_tx_adap[bus_idx],
> +                                     dev->cec_tx_adap[bus_idx]->phys_addr,
> +                                     false);
> +             else
> +                     cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]);
> +
>               break;
>       }
>       return 0;
> diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c 
> b/drivers/media/platform/vivid/vivid-vid-cap.c
> index ca15c13abf6c..0d1ee9a221db 100644
> --- a/drivers/media/platform/vivid/vivid-vid-cap.c
> +++ b/drivers/media/platform/vivid/vivid-vid-cap.c
> @@ -1750,7 +1750,8 @@ int vidioc_s_edid(struct file *file, void *_fh,
>  {
>       struct vivid_dev *dev = video_drvdata(file);
>       u16 phys_addr;
> -     unsigned int i;
> +     u32 display_present = 0;
> +     unsigned int i, j;
>       int ret;
>  
>       memset(edid->reserved, 0, sizeof(edid->reserved));
> @@ -1760,6 +1761,8 @@ int vidioc_s_edid(struct file *file, void *_fh,
>               return -EINVAL;
>       if (edid->blocks == 0) {
>               dev->edid_blocks = 0;
> +             v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0);
> +             v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0);
>               phys_addr = CEC_PHYS_ADDR_INVALID;
>               goto set_phys_addr;
>       }
> @@ -1778,13 +1781,23 @@ int vidioc_s_edid(struct file *file, void *_fh,
>       dev->edid_blocks = edid->blocks;
>       memcpy(dev->edid, edid->edid, edid->blocks * 128);
>  
> +     for (i = 0, j = 0; i < dev->num_outputs; i++)
> +             if (dev->output_type[i] == HDMI)
> +                     display_present |=
> +                             dev->display_present[i] << j++;
> +
> +     v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present);
> +     v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present);
> +
>  set_phys_addr:
>       /* TODO: a proper hotplug detect cycle should be emulated here */
>       cec_s_phys_addr(dev->cec_rx_adap, phys_addr, false);
>  
>       for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)
>               cec_s_phys_addr(dev->cec_tx_adap[i],
> -                             v4l2_phys_addr_for_input(phys_addr, i + 1),
> +                             dev->display_present[i] ?
> +                             v4l2_phys_addr_for_input(phys_addr, i + 1) :
> +                             CEC_PHYS_ADDR_INVALID,
>                               false);
>       return 0;
>  }
> diff --git a/drivers/media/platform/vivid/vivid-vid-common.c 
> b/drivers/media/platform/vivid/vivid-vid-common.c
> index 10a344c29a1a..1f33eb1a76b6 100644
> --- a/drivers/media/platform/vivid/vivid-vid-common.c
> +++ b/drivers/media/platform/vivid/vivid-vid-common.c
> @@ -887,6 +887,8 @@ int vidioc_g_edid(struct file *file, void *_fh,
>                       return -EINVAL;
>               if (dev->output_type[edid->pad] != HDMI)
>                       return -EINVAL;
> +             if (!dev->display_present[edid->pad])
> +                     return -ENODATA;
>               bus_idx = dev->cec_output2bus_map[edid->pad];
>               adap = dev->cec_tx_adap[bus_idx];
>       }
> 

Reply via email to