media: vivid: add display present control

Add a custom control for selecting the presence of a display connected
to the active output. This control is part of an effort to implement
proper HDMI (dis)connect behavior for vivid.

Signed-off-by: Johan Korsnes <johan.korsnes@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Johan Korsnes 2019-06-18 03:37:20 -04:00 committed by Mauro Carvalho Chehab
parent 6c396c28dc
commit c533435ffb
4 changed files with 29 additions and 0 deletions

View file

@ -730,6 +730,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
for (i = 0; i < dev->num_outputs; i++) {
dev->output_type[i] = ((output_types[inst] >> i) & 1) ? HDMI : SVID;
dev->output_name_counter[i] = out_type_counter[dev->output_type[i]]++;
dev->display_present[i] = true;
}
dev->has_audio_outputs = out_type_counter[SVID];
if (out_type_counter[HDMI] == 16) {
@ -1038,6 +1039,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
goto unreg_dev;
/* enable/disable interface specific controls */
if (dev->num_outputs && dev->output_type[0] != HDMI)
v4l2_ctrl_activate(dev->ctrl_display_present, false);
if (dev->num_inputs && dev->input_type[0] != HDMI) {
v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode, false);
v4l2_ctrl_activate(dev->ctrl_dv_timings, false);

View file

@ -225,6 +225,7 @@ struct vivid_dev {
struct v4l2_ctrl *ctrl_dv_timings_signal_mode;
struct v4l2_ctrl *ctrl_dv_timings;
};
struct v4l2_ctrl *ctrl_display_present;
struct v4l2_ctrl *ctrl_has_crop_cap;
struct v4l2_ctrl *ctrl_has_compose_cap;
struct v4l2_ctrl *ctrl_has_scaler_cap;
@ -349,6 +350,7 @@ struct vivid_dev {
u8 *scaled_line;
u8 *blended_line;
unsigned cur_scaled_line;
bool display_present[MAX_OUTPUTS];
/* Output Overlay */
void *fb_vbase_out;

View file

@ -68,6 +68,7 @@
#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41)
#define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)
#define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43)
#define VIVID_CID_DISPLAY_PRESENT (VIVID_CID_VIVID_BASE + 44)
#define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
#define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
@ -944,6 +945,12 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
if (dev->loop_video)
vivid_send_source_change(dev, HDMI);
break;
case VIVID_CID_DISPLAY_PRESENT:
if (dev->output_type[dev->output] != HDMI)
break;
dev->display_present[dev->output] = ctrl->val;
break;
}
return 0;
}
@ -982,6 +989,15 @@ static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = {
.step = 1,
};
static const struct v4l2_ctrl_config vivid_ctrl_display_present = {
.ops = &vivid_vid_out_ctrl_ops,
.id = VIVID_CID_DISPLAY_PRESENT,
.name = "Display Present",
.type = V4L2_CTRL_TYPE_BOOLEAN,
.max = 1,
.def = 1,
.step = 1,
};
/* Streaming Controls */
@ -1588,6 +1604,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
0, V4L2_DV_TX_MODE_HDMI);
dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out,
&vivid_ctrl_display_present, NULL);
}
if ((dev->has_vid_cap && dev->has_vid_out) ||
(dev->has_vbi_cap && dev->has_vbi_out))

View file

@ -1094,6 +1094,12 @@ int vidioc_s_output(struct file *file, void *priv, unsigned o)
dev->vbi_out_dev.tvnorms = dev->vid_out_dev.tvnorms;
vivid_update_format_out(dev);
v4l2_ctrl_activate(dev->ctrl_display_present, vivid_is_hdmi_out(dev));
if (vivid_is_hdmi_out(dev))
v4l2_ctrl_s_ctrl(dev->ctrl_display_present,
dev->display_present[dev->output]);
return 0;
}