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 <[email protected]>
> ---
> 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];
> }
>